password_hash 함수
사실 md5 함수와 이를 이용한 비밀번호 솔팅(salting)은
구식으로 간주됩니다.
우리가 그것을 배운 이유는 여러분이 이후 내용을 이해하고,
또한 다른 사람들의 프로젝트를 작업할 때 마주칠 수 있기
때문입니다.
솔팅된 비밀번호를 얻는 더 나은 방법이 존재합니다.
이를 위해 password_hash 함수가 사용됩니다.
첫 번째 매개변수로 문자열을, 두 번째 매개변수로 암호화
알고리즘을 받아(이는 나중에 설명합니다) 해당 문자열의 해시와
솔트(salt)를 함께 반환합니다.
다음 코드를 여러 번 실행해 보세요:
<?php
echo password_hash('12345', PASSWORD_DEFAULT);
?>
매번 다른 결과를 얻게 될 것이며, 이 결과 문자열에서 첫 부분은 솔트(salt)가, 두 번째 부분은 솔팅된 비밀번호가 됩니다.
password_hash 함수로부터 얻은 해시와 어떤 비밀번호가
있다고 가정해 봅시다.
이 해시가 해당 비밀번호의 것인지 확인하려면
password_verify 함수를 사용해야 합니다.
이 함수는 첫 번째 매개변수로 비밀번호를,
두 번째 매개변수로 해시를 받아 true
또는 false를 반환합니다.
예제를 살펴보겠습니다:
<?php
$password = '12345'; // 비밀번호
$hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // 해시
if (password_verify($password, $hash)) {
// 이 비밀번호의 해시입니다
} else {
// 이 비밀번호의 해시가 아닙니다
}
?>
이것이 실제로 우리에게 주는 이점: 데이터베이스에 솔트를 저장하기 위한 별도의 필드를 만들 필요가 없으며, 이 솔트를 생성하는 데 신경 쓸 필요도 없습니다. PHP가 모든 것을 대신해 줄 것입니다!
즉, 데이터베이스의 password 필드에는 솔트와 함께한
솔팅된 비밀번호를 저장하게 됩니다. 이때 해시된 비밀번호는
더 긴 길이를 가집니다. 따라서 데이터베이스에서 비밀번호
필드의 크기를 수정하여 60 문자로 설정해야 합니다.
이제 등록 코드를 수정해 보겠습니다. 현재 있는 코드는 다음과 같습니다:
<?php
function generateSalt()
{
$salt = '';
$saltLength = 8; // 솔트 길이
for($i = 0; $i < $saltLength; $i++) {
$salt .= chr(mt_rand(33, 126)); // ASCII 테이블의 문자
}
return $salt;
}
$salt = generateSalt(); // 솔트
$password = md5($salt . $_POST['password']); // 비밀번호를 솔팅된 해시로 변환
?>
password_hash를 사용하면 이를 다음과 같이 줄일 수 있습니다:
<?php
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
?>
인증 코드도 비슷하게 수정됩니다:
<?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 {
// 해당 로그인의 사용자가 없음, 메시지 출력
}
?>
여러분의 인증 및 등록 기능을 새로 배운 함수들을 사용하도록 수정하세요.