امنیت در Golang – انجمن DEV

چگونه کد امن تری در Go بنویسیم؟
این بار، ما به بررسی عملکردهای آن می پردازیم hash
و از cifrado/decifrado
با تفاوت اصلی آن به عنوان یک امتیاز، بررسی عملکردهای شبه تصادفی زبان.
- مقدمه
- هش کان SHA512
- کاربردهای رایج هش کردن
- رمزگذاری و رمزگشایی
- کاربردهای رایج رمزگذاری
- اعداد تصادفی
- نتیجه گیری
مقدمه
برای شروع، ما بسته Crypto را داریم stdlib 100٪ (تقریباً همیشه) خدمات مورد نیاز ما را در اختیار ما قرار می دهد. به همین دلیل است که برای حل شبهات اجرایی و درک جزئیات، داشتن اسناد رسمی آن مهم است.
دوم، اما به همان اندازه مهم، این است که این عملیات “یک طرفه” است، یعنی در نتیجه نمی توانم به عقب برگردم و مقدار وارد شده را دریافت کنم.
هش کان SHA512
مطمئنا شما مخفف SHA را در جایی از وب، دوره و غیره دیده اید. این الگوریتم در سال 2001 توسط NSA در ایالات متحده توسعه یافت و در همان سال برای استفاده از آن تأیید شد، انواعی از الگوریتم وجود دارد که با SHA-0 شروع میشود (سپس 1، 2 و 3 که الگوریتم فعلی است، آمد). و 512 به اندازه در بیت اشاره دارد از “خروج” یا هضم به انگلیسی.
توضیح عملیات اصلی بدون پرداختن به مسائل فنی بسیار ساده است: ورودی (آرایه ای از بایت ها) با هر اندازه ای را دریافت می کند و کلمه ای با طول همیشه یکسان (در این مورد 512 بیت) را برمی گرداند. لازم به ذکر است که ورودی می تواند واقعاً بزرگ باشد، طبق داده های رسمی (2^128-1) است.
ما قبلاً می دانیم که آنها چگونه کار می کنند، اکنون یک مشکل کوچک است که قرار نیست آن را پیدا کنیم، اما اگر کسانی که در توسعه این راه حل های خارق العاده نقش دارند، این بود که با داشتن اندازه خروجی تعریف شده و ظرفیت بسیار زیاد برای دریافت مقادیر زیاد، آنها متوجه شد که از اینکه ورودیهای مختلف پاسخ یکسانی دارند، که معمولاً برخورد نامیده میشود، شگفتآور نیست.
خبر خوب این است که از SHA-2
آنها دوباره ملاقات نکردند و این چیزی است که ما نباید نگران آن باشیم.
حالا کمی به سراغ کد می رویم
// hashShortVersion simplemente usa la función para del package, devuelve slice de bytes, simple y efectivo.
func hashShortVersion(s string) string {
hasher := sha512.Sum512([]byte(s))
return fmt.Sprintf("%x", hasher)
}
// hasherVersion creamos una interface hash.Hasher, le asignamos una implemntación de sha512 y usamos el método sum de la interface. Nos puede servir para hacer composición o polimorfismo, el resultado es distinto al anterior.
func hasherVersion(s string) string {
var hasher hash.Hash
hasher = sha512.New()
b := hasher.Sum([]byte(s))
res := fmt.Sprintf("%x", b)
return res
}
// binaryVersion convierte a binario nuestros datos.
func binaryVersion(s string) string {
var hasher hash.Hash
hasher = sha512.New()
hasher.Write([]byte(s))
m, _ := hasher.(encoding.BinaryMarshaler)
_, _ = m.MarshalBinary()
return string(hasher.Sum(nil))
}
از آنجایی که آنها هم کد و هم نظرات را بیان می کنند، نتایج یکسان نیستند زیرا از روش ها/توابع مختلف استفاده می کنند. او MarshallBinary()
استفاده برای ذخیره داده ها در یک ذخیره سازی “عادی” مانند پایگاه داده رابطه ای، سند یا فایل توصیه نمی شود زیرا فرمت بسیار متفاوتی دارد، علاوه بر اینکه برای انسان ناخوانا است و نمی توانیم آن را با اپراتور مقایسه کنیم. "=="
.
رایج ترین کاربردها
گفتیم که توابع هش هدف گرفتن یک ورودی، “هضم” آن و برگرداندن نتیجه ای با اندازه یکسان هستند. مهم نیست وارد شویم یک کاراکتر، کل دن کیشوت یا کل کد منبع هسته لینوکس، خروجی همیشه طول یکسانی دارد. و مانند هر تابع خالص، با توجه به ورودی یکسان، خروجی یکسانی خواهیم داشت، به همین دلیل است رایج ترین استفاده این است که اصالت یک نرم افزار را تضمین کنیم، زمانی که ما SHA a را تحویل می دهیم کامپایل یا قابل اجرا، کاربری که آن را دانلود می کند می تواند همان فرآیند را انجام دهد و تأیید کند که همان طور که اسناد رسمی می گوید بارگیری کرده است.
از طرف دیگر، استفاده بسیار رایجی که من توصیه نمی کنم برای رمزهای عبور است، زیرا جداول با داده های زیادی به نام جداول رنگین کمان وجود دارد که برای این کار استفاده می شود. ترک خوردگی پسوردها، بنابراین مورد استفاده موفقی نیست.
خب تا اینجا هش کردن، اکنون به رمزگذاری می پردازیم
رمزگذاری و رمزگشایی
تفاوت اصلی با هش در این است که در اینجا می توانیم آنچه را که در ابتدا ارسال کرده ایم دریافت کنیم و دوم این که با همان ورودی، به دلیل توابع ریاضی پیچیده نمی توانیم خروجی یکسانی داشته باشیم (هرچه برخورد کمتر باشد، بهتر است) نامیده میشود سال (یا نمک در انگلیسی) و مجموعه ای از بیت های تصادفی است که هدف آن دقیقاً نتیجه را به همان مقادیر ورودی تغییر دهید.
نمونه کد:
func Encrypt(s string) ([]byte, error) {
return bcrypt.GenerateFromPassword([]byte(s), bcrypt.MinCost) // puede ser también defaultCost
}
func Decrypt(encryptedPassword, plainPassword string) error {
return bcrypt.CompareHashAndPassword([]byte(encryptedPassword), []byte(plainPassword))
}
خوب با این یکی ما نمی توانیم شکایت کنیم، چقدر آسان و واضح است جایی برای شک باقی نمی گذارد.
اگر سعی کنید فقط چاپ کنید رشته چندین بار با ورودی یکسان نتیجه می دهند، می توانید ببینید که چگونه نتایج متفاوتی دریافت می کنند.
رایج ترین کاربردها
واضح است که رایج ترین کاربرد (سالها پیش) مخفی کردن یک پیام است تا گیرنده بتواند آن را تفسیر کند. در محاسبات ما به طور گسترده از آن برای رمزهای عبور، نشانه ها و مقادیری که کاربر ارسال می کند و حساس هستند استفاده می کنیم.
اعداد تصادفی
قبل از شروع به پرداختن به موضوع، آنها تصادفی نیستند، شبه تصادفی هستند و یک تعریف نظری است که می توانید در اینجا توضیح دهید.
در این کد، دو مورد استفاده بسیار متداول را می بینیم، اولین مورد این است که یک رشته تصادفی با یک الفبا دریافت کنید. پارامتر ورودی تنها یک است و مربوط به طول رشته به دست آمده است. خیلی ساده و آسان.
تابع دوم کمی بیشتر از آن است، با این تفاوت که ما فقط اعداد را تولید می کنیم و پارامتر ورودی مطابق با حد بالایی است بدون اینکه آن را درج کنیم، یعنی اگر قرار دهیم 1000
، می خواهیم یک عدد بین تولید کنیم 0
y 999
.
func GenerateRandomString(n int) (string, error) {
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
ret := make([]byte, 0, n)
for i := 0; i < n; i++ {
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
if err != nil {
return "", err
}
ret = append(ret, letters[num.Int64()])
}
return string(ret), nil
}
func GenerateRandNum(n int) int64 {
b, err := rand.Int(rand.Reader, big.NewInt(int64(n)))
if err != nil {
return 0
}
return b.Int64()
}
با این دو snippets
آنها قبلاً پرونده های کافی برای پوشش دارند.
نتیجه گیری
ما تفاوت های اصلی بین هش و رمزگذاری را یاد گرفتیم (یا مرور کردیم)، هم از نظر مفهومی به عنوان پیاده سازی در Golang و هم بیشترین کاربردهای آن در صنعت، و هم پیشرفت های دانشگاهی.
در نهایت، به طور خلاصه توضیح دادیم که بسته crypto.Rand چیست و چگونه از آن استفاده کنیم، و به وضوح، کمی کد اضافه کردیم.
می دانید، اگر می خواهید از من حمایت مالی کنید، می توانید این کار را اینجا انجام دهید!