Miễn 100% phí hồ sơ du học Nhật + Tặng 5~9 triệu/bạn

Thursday, February 8, 2018

[Lập trình] Vì sao phải mã hóa password?

Gọi là "hash"  hay "hashing". Bạn không nên lưu trữ password người dùng ở dạng nguyên vì nếu bị tin tặc đột nhập thì họ sẽ thấy ngay được mật khẩu người dùng. Bạn nào định du học ngành IT tại Nhật để vừa biết tiếng Nhật vừa biết IT để làm kỹ sư cầu nối (BrSE = bridge system engineer), dịch giả IT (IT communicator) hay quản lý dự án IT (IT project manager, PM) thì hãy chịu khó mày mò nhé. Quan trọng là ứng dụng được và hiểu nguyên lý.
>>Làm thế nào để học lập trình >>Trang lập trình

Why should I hash passwords supplied by users of my application?Password hashing is one of the most basic security considerations that must be made when designing any application that accepts passwords from users. Without hashing, any passwords that are stored in your application's database can be stolen if the database is compromised, and then immediately used to compromise not only your application, but also the accounts of your users on other services, if they do not use unique passwords.
KB: http://php.net/manual/en/faq.passwords.php

Hash dùng các hàm mã hóa (encrypt) nhanh như SHAR1() hay MD5() không phù hợp cho password vì dễ bị tấn công "brute force" (nói nôm na là thử mọi khả năng).

Xem ở KB (knowledge base) trên.

Tham khảo: PHP
sha1() - Calculate the sha1 hash of a string
sha1_file() - Calculate the sha1 hash of a file
crc32() - Calculates the crc32 polynomial of a string
md5() - Calculate the md5 hash of a string
hash() - Generate a hash value (message digest)
crypt() - One-way string hashing
password_hash() - Creates a password hash

Để tránh vấn đề này thì sẽ dùng "salt" (muối), là thứ được rắc thêm vào cho có thêm hương vị.

Mã hóa password trong PHP - thực hành

Dùng hàm password_hash.

Ví dụ:
<?php
/**
 * We just want to hash our password using the current DEFAULT algorithm.
 * This is presently BCRYPT, and will produce a 60 character result.
 *
 * Beware that DEFAULT may change over time, so you would want to prepare
 * By allowing your storage to expand past 60 characters (255 would be good)
 */
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
?>

Để kiểm tra password có đúng không thì dùng password_verify:

Ví dụ:
<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>
Nếu bạn muốn bảo mật password trong SQL database:
Storing passwords in a secure way in a SQL Server database
https://www.mssqltips.com/sqlservertip/4037/storing-passwords-in-a-secure-way-in-a-sql-server-database/

THỰC HÀNH

Chắc không gì tốt bằng thực hành. Vì chỉ có KINH NGHIỆM mới thành TRI THỨC thôi.

Chuỗi mã hóa (string):    

           

Ví dụ bạn nhập chuỗi "hello" (không có nháy kép) và bấm nút tương ứng.

Kết quả:
SHA1: aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d (KHÔNG THAY ĐỔI)
MD5: 5d41402abc4b2a76b9719d911017c592 (KHÔNG THAY ĐỔI)
CRYPT: Ví dụ $1$t6x31N3t$7/XBfVwMNsdF88Hhuu5J60 (THAY ĐỔI MỖI LẦN)
PASSWORD_HASH:
Ví dụ $2y$10$ZB837GUGj.tVTQMHBuizS.LjVE6gDRvXEqmSvQBUGs3WSG.kklRXa
(THAY ĐỔI MỖI LẦN)

Sở dĩ hàm crypt() và password_hash() thay đổi kết quả là vì có SALT. Nếu không có SALT, passpord rất dễ bị hack bởi tin tặc, chỉ cần sinh sẵn một bảng Sha1 hay Md5 rồi tra như tra từ điển.

Như vậy, SHA1 hay MD5 chỉ là để che mắt người thường là chính, không thể che mắt "thợ khóa" (hacker) mãi được.

Mark

P/S: Nội dung các file PHP để mã hóa trong bài
sha1.php
<?php
$output = "";
if (isset($_GET['string'])) {
$output = sha1($_GET['string']);
} else {
$output = "Please provide 'string' parameter.";
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
</head>
    <body>
<?php echo $output; ?>
    </body>
</html>
md5.php
<?php
$output = "";
if (isset($_GET['string'])) {
$output = md5($_GET['string']);
} else {
$output = "Please provide 'string' parameter.";
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
</head>
    <body>
<?php echo $output; ?>
    </body>
</html>
crypt.php
<?php
$output = "";
if (isset($_GET['string'])) {
$output = crypt($_GET['string']);
} else {
$output = "Please provide 'string' parameter.";
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
</head>
    <body>
<?php echo $output; ?>
    </body>
</html>
password_hash.php
<?php
$output = "";
if (isset($_GET['string'])) {
$output = password_hash($_GET['string'], PASSWORD_DEFAULT);
} else {
$output = "Please provide 'string' parameter.";
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
</head>
    <body>
<?php echo $output; ?>
    </body>
</html>
Còn đây là đoạn Javascript trong bài này để mở các file trên:
<script>
var url = "http://my.meonn.com/tools/";
function funClear() {
    document.getElementsByName("mystring")[0].value="";
}
function funSha1() {
    var x = document.getElementsByName("mystring")[0].value;
    window.open(url + "sha1.php?string=" + x,'_blank');
}
function funMd5() {
    var x = document.getElementsByName("mystring")[0].value;
    window.open(url + "md5.php?string=" + x,'_blank');
}
function funCrypt() {
    var x = document.getElementsByName("mystring")[0].value;
    window.open(url + "crypt.php?string=" + x,'_blank');
}
function funPasswordHash() {
    var x = document.getElementsByName("mystring")[0].value;
    window.open(url + "password_hash.php?string=" + x,'_blank');
}
</script>
Chuỗi  mã hóa (<b><span style="color: red;">string</span></b>): <input autocomplete="on" id="mystring" name="mystring" type="text" />&nbsp;&nbsp;&nbsp;<button onclick="funClear()">Xóa</button><br />
<br />
<button onclick="funSha1()">SHA1</button>&nbsp;&nbsp;&nbsp;
<button onclick="funMd5()">MD5</button>&nbsp;&nbsp;&nbsp;
<button onclick="funCrypt()">CRYPT</button>&nbsp;&nbsp;&nbsp;
<button onclick="funPasswordHash()">PASSWORD_HASH</button>
<br />
Have fun!

More reading: PHP - Encrypting Passwords

No comments:

Post a Comment