Go’da heshlash va Base64 bilan ishlash
Heshlash (hashing) — ixtiyoriy uzunlikdagi ma’lumotdan belgilangan uzunlikdagi xesh qiymat, ya’ni digest hosil qilish jarayoni. Fayl yuklashda uning buzilmaganini tekshirish, cache kaliti yaratish va xabarni autentifikatsiya qilish kabi vazifalarda xesh funksiyalari ishlatiladi.
Xesh, kodlash va shifrlash bir xil tushuncha emas. Ularni aralashtirish xavfsizlik xatolariga olib keladi:
- xesh — odatda bir tomonlama o‘zgartirish;
- Base64 — qayta ochiladigan matnli kodlash;
- shifrlash (encryption) — kalit yordamida qayta ochiladigan himoya;
- HMAC — maxfiy kalit bilan xabarning yaxlitligi va haqiqiyligini tekshirish.
Xesh funksiyasining asosiy xususiyatlari
Yaxshi kriptografik xesh funksiyasi quyidagi xususiyatlarga ega:
- bir xil kirish doim bir xil digest beradi;
- kirishdagi kichik o‘zgarish digestni keskin o‘zgartiradi;
- digestdan dastlabki ma’lumotni tiklash amalda qiyin;
- turli kirishlar uchun bir xil digest topish, ya’ni kolliziya yaratish qiyin bo‘lishi kerak.
Digest uzunligi kirish hajmiga bog‘liq emas. Bo‘sh matn ham, katta fayl ham SHA-256 bilan 256 bit — 32 bayt natija beradi.
Warning
Xesh qiymati ma’lumotni yashirmaydi. Kirish qiymatlari taxmin qilinadigan bo‘lsa, hujumchi ularni xeshlab solishtirishi mumkin. Shu sababli oddiy SHA-256 parollarni saqlash uchun yaramaydi.
SHA-256 bilan birinchi misol
crypto/sha256 paketi SHA-256 hisoblaydi. Natija binary baytlar bo‘lgani uchun uni ko‘rsatishda ko‘pincha hexadecimal kodlash ishlatiladi.
Natija:
sha256.Sum256() []byte qabul qiladi va [32]byte massiv qaytaradi. sum[:] massivdan slice ko‘rinishini yaratadi. hex.EncodeToString() har bir baytni ikkita hexadecimal belgi bilan yozgani uchun natija 64 belgidan iborat.
Bir xil matn qayta xeshlansa, natija o‘zgarmaydi. Hatto bitta harf yoki bo‘sh joy o‘zgarsa, boshqa digest chiqadi. Xesh matnning kodlangan baytlariga hisoblanadi; Salom va salom, shuningdek, Unicode yozilishining turli shakllari bir xil ma’no bersa ham turli baytlar bo‘lishi mumkin.
fmt hexadecimal ko‘rinishni bevosita ham chiqara oladi:
Bu qisqa parcha encoding/hex importisiz digestni ko‘rsatadi. %x baytlarni kichik harfli hexadecimal formatda yozadi.
Katta ma’lumotni oqim sifatida heshlash
Katta faylni to‘liq RAMga yuklash shart emas. sha256.New() hash.Hash interfeysini qaytaradi va ma’lumotni bo‘laklab qabul qiladi.
Natija 64 belgili SHA-256 digest bo‘ladi:
io.Copy() ma’lumotni sourcedan bo‘laklab hasherga yozadi. hasher.Sum(nil) shu paytgacha yozilgan barcha baytlar digestini qaytaradi. Real faylda strings.NewReader() o‘rniga os.Open()dan olingan fayl ishlatiladi. Oqimli usul xotira sarfini fayl hajmiga bog‘lab qo‘ymaydi.
hash.Hashga Write() chaqirish digestni darhol qaytarmaydi; ichki holatni yangilaydi. Sum(nil) hisoblangan natijani oladi, lekin hasher holatini reset qilmaydi. Yangi mustaqil hisob uchun Reset() yoki yangi hasher kerak.
MD5 va SHA-1 nega xavfsiz emas?
MD5 128 bit, SHA-1 esa 160 bit digest yaratadi. Ikkalasida ham amaliy kolliziya hujumlari mavjud. Hujumchi turli ikki faylga bir xil digest yasashi mumkin bo‘lgan xavfsizlik kontekstida bu algoritmlarni ishlatib bo‘lmaydi.
MD5 faqat legacy protokol bilan moslik yoki xavfsizlikka aloqasiz eski checksum formati talab qilinganda uchrashi mumkin:
Natija:
Natija 16 bayt, hexadecimal ko‘rinishda 32 belgi. Kod texnik jihatdan ishlaydi, ammo MD5’ni parol, raqamli imzo, sertifikat yoki hujumchi o‘zgartira oladigan faylning xavfsizligini tekshirish uchun ishlatmang.
Oddiy xesh autentifikatsiya bermaydi
SHA-256 tasodifiy buzilishni aniqlashi mumkin. Ammo hujumchi xabarni ham, yonidagi digestni ham almashtira olsa, yangi digestni o‘zi hisoblaydi. Xabarning ishonchli manbadan kelganini tekshirish uchun HMAC kerak.
HMAC xesh funksiyasi va faqat ikki tomon biladigan maxfiy kalitdan foydalanadi:
Natija:
Imzo: 12cc899b0604da2c317e5a83dabe7ea5d0daff236a6c33b3714cd33993ac5ea0
Mos: true
O‘zgargan xabar: false
hmac.New() SHA-256 asosidagi HMAC yaratadi. Xabar yoki kalit o‘zgarsa, imzo mos kelmaydi. hmac.Equal() qiymatlarni vaqt ma’lumotini sizdirmaslikka mos usulda solishtiradi. Xavfsizlik tekshiruvida oddiy bytes.Equal() yoki hexadecimal satrlar uchun == ishlatishdan ko‘ra hmac.Equal()ni tanlang.
Maxfiy kalitni kodga qattiq yozish real loyiha uchun to‘g‘ri emas. Misoldagi qiymat faqat ishlash prinsipini ko‘rsatadi. Production’da kalit secret manager yoki himoyalangan konfiguratsiyadan olinadi.
Base64 xesh emas
Base64 binary ma’lumotni matnda xavfsiz tashish uchun kodlaydi. U maxfiylik bermaydi va kalit talab qilmaydi. Kodlangan qiymatni istalgan kishi qayta dekodlay oladi.
Natija:
Base64 har 3 baytni 4 ta matn belgisiga aylantiradi. Shu sababli natija odatda asl ma’lumotdan qariyb uchdan birga katta bo‘ladi. Oxirdagi = to‘ldiruvchi belgi (padding) hisoblanadi.
Standard va URL-safe Base64
base64.StdEncoding alifbosida + va / bor. URL, cookie yoki fayl nomida ko‘pincha base64.URLEncoding ishlatiladi; ularning o‘rniga - va _ yozadi. Padding kerak bo‘lmasa, base64.RawURLEncoding tanlanadi.
Natija:
Ikkinchi variant URL uchun xavfsiz alifbodan foydalanadi va padding yozmaydi. Encode va decode paytida bir xil variantni ishlatish kerak; aks holda DecodeString() xato qaytarishi mumkin.
Parollarni qanday saqlash kerak?
SHA-256 va SHA-512 tez ishlaydi. Bu fayl yaxlitligi uchun foydali, ammo parol uchun xavfli: hujumchi soniyasiga juda ko‘p taxminni tekshirishi mumkin.
Parol uchun maxsus sekin va sozlanadigan algoritm ishlatiladi:
- Argon2id;
- scrypt;
- bcrypt;
- tashkilot talabi bo‘lsa, PBKDF2.
Ular salt va xarajat parametridan foydalanadi. Salt har bir parol uchun alohida tasodifiy qiymat bo‘lib, bir xil parollar bir xil saqlangan natija bermasligini ta’minlaydi. Salt maxfiy bo‘lishi shart emas; u xesh bilan birga saqlanadi.
Bu algoritmlarning amaliy implementatsiyalari golang.org/x/crypto modulida mavjud. Algoritm va parametr tanlovi xavfsizlik talabi, server resursi va amaldagi tavsiyalarga bog‘liq. Parolni o‘zingiz yaratgan SHA-256(password + salt) sxemasi bilan saqlamang.
Fayl checksumini tekshirish
Fayl yuklab olinganda kutilgan digest ishonchli HTTPS sahifasi yoki imzolangan manifestdan olingan bo‘lsa, SHA-256 fayl buzilmaganini tekshiradi. Faqat fayl bilan bir joydan olingan digest hujumchiga qarshi himoya bermaydi: ikkalasi ham almashtirilishi mumkin.
Digest matnini solishtirishdan oldin formatni tekshiring. SHA-256 hexadecimal qiymati 64 belgidan iborat bo‘lishi kerak. Katta-kichik harf farqini yo‘qotish uchun matnni baytga dekodlab, kutilgan 32 bayt bilan solishtirish mumkin.
Keng tarqalgan xatolar
- Base64’ni shifrlash deb hisoblash. U qayta ochiladigan kodlashdir.
- Parolga oddiy SHA-256 qo‘llash. Tez xesh brute-force hujumini arzonlashtiradi.
- MD5 yoki SHA-1’ni xavfsizlik qarori uchun ishlatish. Ular kolliziyaga chidamli emas.
- Xabar autentifikatsiyasi uchun
SHA-256(key || message)kabi qo‘lbola sxema yaratish. Standart HMAC ishlating. - Katta faylni to‘liq
os.ReadFile()bilan RAMga olish.io.Copy()vahash.Hashbilan oqimli hisoblang. - Xavfsizlik imzosini oddiy
==bilan solishtirish.hmac.Equal()dan foydalaning. - Matnning ko‘rinishi bir xil bo‘lsa, baytlari ham bir xil deb o‘ylash. Kodlash va Unicode normalizatsiyasini protokol darajasida aniq belgilang.
Interviewda nimalarga e’tibor beriladi?
- Xesh, kodlash, shifrlash va HMAC o‘rtasidagi farq.
- Kolliziya, preimage va belgilangan digest uzunligi tushunchalari.
- SHA-256 nega parol saqlash uchun mos emasligi.
sha256.Sum256()qaytaradigan[32]bytevasha256.New()qaytaradiganhash.Hashfarqi.- Base64 hajmi va
StdEncoding,URLEncoding,RawURLEncodingvariantlari. - HMAC imzosini
hmac.Equal()bilan tekshirish sababi.
Xulosa
SHA-256 ma’lumot digestini hisoblaydi, ammo o‘zi xabarning kimdan kelganini isbotlamaydi. HMAC maxfiy kalit bilan yaxlitlik va autentifikatsiyani birlashtiradi. Base64 faqat binary ma’lumotni matnga kodlaydi. MD5 va SHA-1 yangi xavfsizlik yechimlari uchun yaramaydi, parollar esa Argon2id, scrypt yoki bcrypt kabi maxsus password hashing algoritmi bilan saqlanadi.