3-bo‘lim

Xesh funksiyalari

Bir tomonlama funksiyalar, ko'chki effekti, to'qnashuvlar va nima uchun SHA-256 parol uchun yaramaydi.

🕑 13 daqiqa o‘qish 📄 1 000 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Asosiy xususiyatlar
  2. Ko'chki effekti
  3. To'qnashuv nima
  4. Buzilgan algoritmlar
  5. Fayl butunligini tekshirish
  6. Tez hisoblanish - qachon muammo
  7. Yana bir tuzoq: uzunlikni kengaytirish
  8. Qaysi algoritmni tanlash
  9. Xulosa

Xesh funksiyasi - istalgan uzunlikdagi ma'lumotni qat'iy uzunlikdagi qiymatga aylantiruvchi funksiya.

U shifrlash emas: natijani qaytarib bo'lmaydi.

Asosiy xususiyatlar #

PHP
function xeshKorsat(string $nom, string $qiymat, string $algo = 'sha256'): void
{
    printf("%-22s %s%s", $nom, hash($algo, $qiymat), PHP_EOL);
}
PHP
// 1. Aniqlik: bir xil kirish - har doim bir xil chiqish
xeshKorsat('birinchi marta', 'Salom');
xeshKorsat('ikkinchi marta', 'Salom');

// 2. Qat'iy uzunlik: kirish hajmi ahamiyatsiz
$qisqa = hash('sha256', 'a');
$uzun = hash('sha256', str_repeat('a', 1000000));

echo 'bir belgi:    ', strlen($qisqa), ' hex belgi', PHP_EOL;
echo 'million belgi:', strlen($uzun), ' hex belgi', PHP_EOL;
Natija
birinchi marta         441f71d48aacacdc18293201da2bfda40a421c4f93d8e509fcd2d0440b007b46
ikkinchi marta         441f71d48aacacdc18293201da2bfda40a421c4f93d8e509fcd2d0440b007b46
bir belgi:    64 hex belgi
million belgi:64 hex belgi

Ko'chki effekti #

Kirishning bitta biti o'zgarsa, natijaning taxminan yarmi o'zgaradi:

PHP
$a = hash('sha256', 'Salom', true);
$b = hash('sha256', 'Talom', true);   // S -> T, bitta harf

echo 'a: ', bin2hex($a), PHP_EOL;
echo 'b: ', bin2hex($b), PHP_EOL;

// nechta bit farq qilgan?
$farq = 0;
for ($i = 0; $i < strlen($a); $i++) {
    $xor = ord($a[$i]) ^ ord($b[$i]);
    $farq += substr_count(decbin($xor), '1');
}

printf('jami bit:     %d%s', strlen($a) * 8, PHP_EOL);
printf('farq qilgan:  %d bit%s', $farq, PHP_EOL);
printf('foiz:         %.1f%%%s', $farq / (strlen($a) * 8) * 100, PHP_EOL);
Natija
a: 441f71d48aacacdc18293201da2bfda40a421c4f93d8e509fcd2d0440b007b46
b: 40ca9baef6ce07202257706cb661c5bcfb3d3df89591d130bff0edb97a6c58d5
jami bit:     256
farq qilgan:  128 bit
foiz:         50.0%

Bitta harf o'zgarishi natijani butunlay o'zgartirdi. Bu ko'chki effekti (avalanche effect).

Ko'chki effekti nima uchun kerak

Agar u bo'lmasa, o'xshash kirishlar o'xshash xesh berardi. Shunda hujumchi xeshga qarab kirish haqida taxmin qila olardi.

Yaxshi xesh funksiyada:

TalabMa'nosi
AniqlikBir xil kirish - bir xil chiqish
Tez hisoblanishKatta fayl uchun ham amaliy
Bir tomonlamaXeshdan kirishni tiklash imkonsiz
Ikkinchi asl nusxaga chidamlilikBerilgan x uchun hash(y) = hash(x) bo'ladigan y topilmasin
To'qnashuvga chidamlilikUmuman hash(a) = hash(b) bo'ladigan juftlik topilmasin

Uchinchi qatorga e'tibor bering - "tez hisoblanish" yaxshi xususiyat. Lekin parol saqlashda u kamchilikka aylanadi (4-bo'lim).

To'qnashuv nima #

Xesh chiqishi cheklangan, kirish esa cheksiz. Demak to'qnashuvlar matematik jihatdan muqarrar.

Savol faqat ularni topish qanchalik qiyin ekanida.

Buni qisqartirilgan xesh bilan ko'rsatamiz:

PHP
// Xesh natijasining faqat birinchi 3 baytini olamiz - 24 bit
function qisqaXesh(string $matn): string
{
    return substr(hash('sha256', $matn), 0, 6);
}
PHP
$korilgan = [];
$urinish = 0;

while (true) {
    $matn = 'xabar-' . $urinish;
    $x = qisqaXesh($matn);

    if (isset($korilgan[$x])) {
        echo "TO'QNASHUV topildi!", PHP_EOL;
        echo '  1-matn: ', $korilgan[$x], PHP_EOL;
        echo '  2-matn: ', $matn, PHP_EOL;
        echo '  xesh:   ', $x, PHP_EOL;
        echo '  urinish: ', $urinish, PHP_EOL;
        break;
    }

    $korilgan[$x] = $matn;
    $urinish++;
}

// to'liq xeshlar esa butunlay boshqacha
echo PHP_EOL, 'toliq xeshlar:', PHP_EOL;
echo '  ', substr(hash('sha256', $korilgan[$x]), 0, 32), '...', PHP_EOL;
echo '  ', substr(hash('sha256', $matn), 0, 32), '...', PHP_EOL;
Natija
TO'QNASHUV topildi!
  1-matn: xabar-1795
  2-matn: xabar-8758
  xesh:   dad2ab
  urinish: 8758

toliq xeshlar:
  dad2ab8ddb998119462a7e89a3ea4d56...
  dad2ab14f3627e7d67e9c9cc24665101...
Tug'ilgan kun paradoksi

24 bitlik xeshda 2²⁴ ≈ 16.7 million variant bor. Lekin to'qnashuv 16 million urinishdan ancha oldin topildi.

Sabab - tug'ilgan kun paradoksi: n variant orasidan to'qnashuv topish uchun taxminan √n urinish yetarli.

Xesh uzunligiVariantlarTo'qnashuv uchun taxminan
24 bit2²⁴2¹² ≈ 4 000
64 bit2⁶⁴2³² ≈ 4 milliard
128 bit (MD5)2¹²⁸2⁶⁴ - nazariy
256 bit (SHA-256)2²⁵⁶2¹²⁸ - imkonsiz

Shuning uchun xesh uzunligi ikki barobar olinadi: 128 bitlik xavfsizlik uchun 256 bitlik xesh kerak.

Buzilgan algoritmlar #

PHP
$algolar = ['md5', 'sha1', 'sha256', 'sha512', 'sha3-256'];

printf("%-10s %-6s %s%s", 'algoritm', 'bit', 'holati', PHP_EOL);
echo str_repeat('-', 46), PHP_EOL;

$holat = [
    'md5' => 'BUZILGAN - toqnashuv topiladi',
    'sha1' => 'BUZILGAN - toqnashuv topiladi',
    'sha256' => 'ishonchli',
    'sha512' => 'ishonchli',
    'sha3-256' => 'ishonchli',
];

foreach ($algolar as $a) {
    printf("%-10s %-6d %s%s", $a,
        strlen(hash($a, '')) * 4, $holat[$a], PHP_EOL);
}
Natija
algoritm   bit    holati
----------------------------------------------
md5        128    BUZILGAN - toqnashuv topiladi
sha1       160    BUZILGAN - toqnashuv topiladi
sha256     256    ishonchli
sha512     512    ishonchli
sha3-256   256    ishonchli
MD5 va SHA-1 ni yangi kodda ishlatmang
AlgoritmBirinchi to'qnashuvHolati
MD52004Butunlay buzilgan, oddiy noutbukda topiladi
SHA-12017 (SHAttered)Buzilgan, amaliy hujum mavjud
SHA-256Yo'qIshonchli
SHA-3Yo'qIshonchli, boshqa tuzilishga asoslangan

To'qnashuv nimani anglatadi: hujumchi ikkita turli hujjat yasay oladi - biri zararsiz, ikkinchisi zararli - va ikkalasining xeshi bir xil bo'ladi. Siz birinchisini imzolaysiz, hujumchi imzoni ikkinchisiga qo'yadi.

md5 va sha1 hali ham foydali bo'lgan yagona joy - kriptografiya bilan bog'liq bo'lmagan vazifalar:

Ruxsat etiladiTaqiqlanadi
Kesh kalitiParol xeshi
Fayl nomini qisqartirishRaqamli imzo
Tasodifiy bo'lmagan taqsimlashButunlik tekshiruvi
Nusxalarni topish (tez filtr)Sertifikat

Shubha bo'lsa - SHA-256 ishlating.

Xesh funksiyasi - bir tomonlama yo'l Kirish "Salom" 1 baytli fayl 4 GB video butun kutubxona cheksiz variant oson SHA-256 ko'chki effekti aniq, tez Chiqish 32 bayt 64 hex belgi HAR DOIM bir xil uzunlikda 2²⁵⁶ variant × teskari yo'l yo'q Cheksiz kirish, cheklangan chiqish to'qnashuv muqarrar Xesh nima uchun ishlatiladi ✓ Fayl butunligini tekshirish (nusxa ko'chirishda buzilmadimi) ✓ Ma'lumotni o'zgarganini aniqlash (kesh yaroqlimi) ✓ HMAC va imzo qurilishida qurilish bloki sifatida ✗ Parol saqlash - juda TEZ (4-bo'lim) ✗ Yolg'iz o'zi autentiklik bermaydi (5-bo'lim) ✗ Shifrlash o'rniga - qaytarib bo'lmaydi
Xesh - barmoq izi: asl narsani tiklab bo'lmaydi, lekin solishtirish mumkin

Fayl butunligini tekshirish #

PHP
$fayl = tempnam(sys_get_temp_dir(), 'kr');
file_put_contents($fayl, "hisobot\nsatr 1\nsatr 2\n");

$asl = hash_file('sha256', $fayl);
echo 'asl xesh:  ', substr($asl, 0, 24), '...', PHP_EOL;

// nusxa ko'chirdik
$nusxa = $fayl . '.nusxa';
copy($fayl, $nusxa);
echo 'nusxa mos: ', hash_equals($asl, hash_file('sha256', $nusxa))
    ? 'ha' : 'yoq', PHP_EOL;

// bitta bayt o'zgardi
file_put_contents($nusxa, "hisobot\nsatr 1\nsatr 3\n");
echo 'ozgargach: ', hash_equals($asl, hash_file('sha256', $nusxa))
    ? 'ha' : 'yoq', PHP_EOL;

unlink($fayl);
unlink($nusxa);
Natija
asl xesh:  490893ebba0dbf3421bfc535...
nusxa mos: ha
ozgargach: yoq

Tez hisoblanish - qachon muammo #

PHP
$soni = 200000;
$boshlanish = hrtime(true);

for ($i = 0; $i < $soni; $i++) {
    hash('sha256', 'parol' . $i);
}

$sekund = (hrtime(true) - $boshlanish) / 1e9;
$tezlik = $soni / $sekund;

// Aniq raqam mashinaga bog'liq, shuning uchun chegara bilan tekshiramiz
printf('%d ta SHA-256 hisoblandi%s', $soni, PHP_EOL);
printf('bir soniyadan kam vaqtda: %s%s',
    $sekund < 1.0 ? 'ha' : 'yoq', PHP_EOL);
printf('soniyasiga 500 000 dan kop: %s%s',
    $tezlik > 500000 ? 'ha' : 'yoq', PHP_EOL);
echo 'va bu - oddiy noutbuk, PHP da, bitta yadroda', PHP_EOL;
Natija
200000 ta SHA-256 hisoblandi
bir soniyadan kam vaqtda: ha
soniyasiga 500 000 dan kop: ha
va bu - oddiy noutbuk, PHP da, bitta yadroda

Aniq raqam mashinaga bog'liq, lekin tartib doim bir xil: oddiy noutbukda PHP soniyasiga million atrofida SHA-256 hisoblaydi.

Bu tezlik parol uchun halokatli

Yuqoridagi raqamga qarang - va u faqat PHP da, bitta yadroda.

Maxsus uskunada (GPU, ASIC) SHA-256 tezligi butunlay boshqa darajada bo'ladi. Bitcoin tarmog'i soniyasiga kvintillionlab SHA-256 hisoblaydi.

Demak parol xeshlari o'g'irlansa va ular oddiy SHA-256 bilan saqlangan bo'lsa, hujumchi lug'atdagi barcha parollarni juda tez sinab chiqadi.

Yechim - ataylab sekin funksiyalar: bcrypt, Argon2id. Bu keyingi bo'limning mavzusi.

Yana bir tuzoq: uzunlikni kengaytirish #

PHP
// XATO: sirni oldiga qo'yib xeshlash
$sir = 'maxfiy-kalit';
$malumot = 'foydalanuvchi=oddiy&admin=0';

$notogriImzo = hash('sha256', $sir . $malumot);
echo 'notogri usul: ', substr($notogriImzo, 0, 32), '...', PHP_EOL;

// TO'G'RI: HMAC
$togriImzo = hash_hmac('sha256', $malumot, $sir);
echo 'togri usul:   ', substr($togriImzo, 0, 32), '...', PHP_EOL;
Natija
notogri usul: 0ae2a56f7deccd85553830c9bfd53e08...
togri usul:   7fac401a5c4dd50079322dc1097d4c62...
hash($sir . $malumot) - klassik xato

SHA-256 Merkle-Damgard tuzilishiga asoslangan: u ma'lumotni bloklarga bo'lib, holatni ketma-ket yangilab boradi.

Bu shunday xususiyat beradi: hash($sir . $malumot) ni bilgan hujumchi, $sir ning o'zini bilmasa ham, hash($sir . $malumot . $qoshimcha) ni hisoblay oladi.

Ya'ni u imzoni buzmasdan ma'lumotga qo'shimcha qo'sha oladi - masalan &admin=1.

Bu uzunlikni kengaytirish hujumi (length extension).

QurilishXavfsizmi
hash($sir . $malumot)Yo'q
hash($malumot . $sir)Zaifroq, lekin baribir tavsiya etilmaydi
hash_hmac($malumot, $sir)Ha
SHA-3 bilan hash($sir . $malumot)Ha (boshqa tuzilish), lekin baribir HMAC afzal

Qoida: xesh bilan autentiklik kerak bo'lsa - har doim HMAC. Buni keyingi bo'limlardan birida ko'ramiz.

Qaysi algoritmni tanlash #

VazifaTavsiya
Umumiy xeshlash, butunlikSHA-256
Uzun xesh kerakSHA-512
Boshqa tuzilish kerakSHA3-256
ParolArgon2id / bcrypt (hash() emas!)
Xabar autentikligihash_hmac
Kesh kaliti, nusxa filtriMD5 ham mumkin (kriptografik emas)
Amaliy topshiriq
  1. Bir xil matnni ikki marta xeshlang va natijalar bir xilligini tekshiring.
  2. Bir belgi va million belgi uchun xesh uzunligini solishtiring.
  3. Bitta harf o'zgartirib, nechta bit farq qilganini hisoblang.
  4. 3 baytga qisqartirilgan xesh uchun to'qnashuv toping.
  5. Qisqartirishni 4 baytga oshiring - urinishlar soni qanday o'zgardi?
  6. Tug'ilgan kun paradoksini o'z so'zlaringiz bilan tushuntiring.
  7. hash_file bilan fayl butunligini tekshiring.
  8. Faylning bitta baytini o'zgartirib, xesh o'zgarishini ko'ring.
  9. O'z mashinangizda soniyasiga nechta SHA-256 hisoblanishini o'lchang.
  10. hash($sir . $malumot) nima uchun xato ekanini yozing.

Xulosa #

  • Xesh funksiyasi istalgan hajmdagi ma'lumotni qat'iy uzunlikdagi qiymatga aylantiradi.
  • U bir tomonlama: natijadan kirishni tiklab bo'lmaydi.
  • Ko'chki effekti: bitta bit o'zgarsa, natijaning taxminan yarmi o'zgaradi.
  • To'qnashuvlar matematik jihatdan muqarrar - savol ularni topish qiyinligida.
  • Tug'ilgan kun paradoksi: n variant uchun √n urinish yetarli.
  • Shuning uchun 128 bitlik xavfsizlikka 256 bitlik xesh kerak.
  • MD5 va SHA-1 buzilgan - kriptografik maqsadda ishlatilmaydi.
  • Xesh tez hisoblanadi - bu butunlik uchun yaxshi, parol uchun halokatli.
  • hash($sir . $malumot) uzunlikni kengaytirish hujumiga ochiq.
  • Xabar autentikligi kerak bo'lsa - hash_hmac.

Keyingi bo'limda parollarni to'g'ri saqlash bilan tanishamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.