ฟังก์ชัน password_hash

ในความเป็นจริงแล้ว ฟังก์ชัน md5 และการใส่เกลือ รหัสผ่านด้วยมันนั้นถือว่าล้าสมัยแล้ว เราศึกษามันเพื่อให้คุณเข้าใจเนื้อหา ต่อไป รวมถึงเพราะคุณอาจจะพบเจอ สิ่งนี้ เมื่อทำงานกับโปรเจคของคนอื่น

มีวิธีที่ก้าวหน้าและดีกว่าในการได้ รหัสผ่านที่ใส่เกลือมา สำหรับสิ่งนี้ใช้ฟังก์ชัน password_hash พารามิเตอร์แรกมัน รับสตริง และพารามิเตอร์ที่สอง - อัลกอริทึมการเข้ารหัส (จะพูดถึงทีหลัง) และส่งกลับแฮชของสตริงนั้น พร้อมกับเกลือ

ลองรันโค้ดนี้หลายๆ ครั้งดู:

html<?php
  echo password_hash('12345', PASSWORD_DEFAULT);
?>

คุณจะได้ผลลัพธ์ที่แตกต่างกันทุกครั้ง และในผลลัพธ์นี้ส่วนแรกของสตริงจะ เป็นเกลือ และส่วนที่สอง - รหัสผ่านที่ใส่เกลือแล้ว

สมมติว่าเรามีแฮชที่ได้จากฟังก์ชัน password_hash และรหัสผ่านบางรหัส เพื่อ ตรวจสอบว่า นี่คือแฮชของรหัสผ่านนี้หรือไม่ ควรใช้ฟังก์ชัน password_verify - พารามิเตอร์แรกมันรับรหัสผ่าน และพารามิเตอร์ที่สอง - แฮช และส่งกลับ true หรือ false

ลองดูตัวอย่าง:

html<?php
  $password = '12345'; // รหัสผ่าน
  $hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // แฮช
  
  if (password_verify($password, $hash)) {
    // แฮชจากรหัสผ่านนี้
  } else {
    // แฮชไม่ใช่จากรหัสผ่านนี้
  }
?>

สิ่งนี้ให้อะไรเราในทางปฏิบัติ: เราสามารถไม่ ต้องสร้างฟิลด์แยกในฐานข้อมูลสำหรับ เก็บเกลือ ไม่ต้องกังวลกับการสร้าง เกลือนี้ - PHP จะทำทุกอย่างให้เรา!

นั่นคือมันจะกลายเป็นว่า ในฐานข้อมูลในฟิลด์ password เราจะเก็บรหัสผ่านที่ใส่เกลือแล้ว พร้อมกับเกลือของมัน ในขณะเดียวกันรหัสผ่านที่ถูกแฮช จะมีความยาวมากกว่า ดังนั้น ในฐานข้อมูลเราจำเป็นต้องแก้ไขขนาด ของฟิลด์รหัสผ่านและตั้งค่าให้เป็น 60 ตัวอักษร

ตอนนี้เรามาแก้ไขโค้ดการลงทะเบียนกัน นี่คือสิ่งที่เรามีอยู่ตอนนี้:

html<?php
  function generateSalt()
  {
    $salt = '';
    $saltLength = 8; // ความยาวเกลือ
    
    for($i = 0; $i < $saltLength; $i++) {
      $salt .= chr(mt_rand(33, 126)); // อักขระจาก ASCII-table
    }
    
    return $salt;
  }
  
  $salt = generateSalt(); //  เกลือ
  $password = md5($salt . $_POST['password']); // แปลงรหัสผ่านเป็นแฮชที่ใส่เกลือ
?>

ด้วย password_hash เราสามารถย่อสิ่งนี้เหลือ:

html<?php
  $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
?>

ในทำนองเดียวกันโค้ดการเข้าสู่ระบบก็จะถูกปรับ:

html<?php
  $login = $_POST['login'];
  
  $query = "SELECT * FROM users WHERE login='$login'"; // ได้ผู้ใช้จากล็อกอิน
  $res = mysqli_query($link, $query);
  $user = mysqli_fetch_assoc($res);
  
  if (!empty($user)) {
    $hash = $user['password']; // รหัสผ่านที่ใส่เกลือจาก DB
    
    // ตรวจสอบความสอดคล้องของแฮชจากฐานข้อมูลกับรหัสผ่านที่ป้อนเข้ามา
    if (password_verify($_POST['password'], $hash)) {
      // ทุกอย่างโอเค, เข้าสู่ระบบ...
    } else {
      // รหัสผ่านไม่ตรง, แสดงข้อความ
    }
  } else {
    // ไม่มีผู้ใช้ที่มีล็อกอินนี้, แสดงข้อความ
  }
?>
Задание 1

ปรับกระบวนการเข้าสู่ระบบและการลงทะเบียนของคุณ ให้ใช้ฟังก์ชันใหม่ที่ได้เรียนรู้ไป