DB에 패스워드를 안전하게 저장하기 위해서는 단방향 해시 함수를 사용하게 된다.

이유는 DB가 외부로 유출 되었을 때, 패스워드의 평문을 알아내기 어렵게 하기 위해서 이다.

 

php에서 사용자의 패스워드를 해시 해주는 password_hash() 함수와, 사용자가 입력한 패스워드랑 해시된 패스워드를 비교해주는 password_verify() 함수가 있다.

 


password_hash()

password_hash()는 2개의 인자가 필요하다.

첫번재 인자는 해시할 패스워드, 두번째는 암호 알고리즘이다.

Return 값은 해시 과정에서 에러 발생 시 false, 성공하면 문자열의 해시 값을 준다.

password_hash ( string $password , int $algo [, array $options ] ) : string

// 출처: https://www.php.net/manual/en/function.password-hash.php

 

암호 알고리즘의 종류는 아래와 같다.

PASSWORD_DEFAULT - Use the bcrypt algorithm (default as of PHP 5.5.0). Note that this constant is designed to change over time as new and stronger algorithms are added to PHP. For that reason, the length of the result from using this identifier can change over time. Therefore, it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice).
PASSWORD_BCRYPT - Use the CRYPT_BLOWFISH algorithm to create the hash. This will produce a standard crypt() compatible hash using the "$2y$" identifier. The result will always be a 60 character string, or FALSE on failure.
PASSWORD_ARGON2I - Use the Argon2i hashing algorithm to create the hash. This algorithm is only available if PHP has been compiled with Argon2 support.
PASSWORD_ARGON2ID - Use the Argon2id hashing algorithm to create the hash. This algorithm is only available if PHP has been compiled with Argon2 support.

// 출처: https://www.php.net/manual/en/function.password-hash.php

 

 

사용자가 어떤 홈페이지에 가입을 하려고 한다.

서버는 POST 방식으로 데이터를 받아 아래 코드처럼 password_hash() 함수를 통해 패스워드를 해시 한다.

그 후 DB에 그 값을 저장한다.

<?php
    if(isset($_POST['password'])){
        // DB connect
        include "./db.php";
        
        $user_pw = $_POST['password'];
        $password = password_hash($user_pw, PASSWORD_DEFAULT);
        // Result example: $2y$10$B1ybiCIuv8k13ErqSogkdORDKJKK15xFVKVEAWNq7x0TG6SNThf2u
        
        // Insert into DB
        // ...
    }
?>

 

사용자의 패스워드가 test일 경우 결과가

$2y$10$B1ybiCIuv8k13ErqSogkdORDKJKK15xFVKVEAWNq7x0TG6SNThf2u 

라고 출력이 된다. 이 값은 PASSWORD_DEFAULT 암호 알고리즘의 특성상 시간에 따라 해시의 결과가 달라진다.

 

 

 


password_verify()

해시된 패스워드와 사용자가 입력한 패스워드와 비교하기 위해서는 password_verify() 함수를 사용해야 한다.

이 함수의 Return 값은 2개의 인자 값을 비교해서 같으면 True, 다르면 false를 반환한다.

password_verify ( string $password , string $hash ) : bool

 

아래 코드를 통해 예를 들어 설명하면 다음과 같다.

<?php
    $user_pw = $_POST['password'];
    $hash_pw = '$2y$10$B1ybiCIuv8k13ErqSogkdORDKJKK15xFVKVEAWNq7x0TG6SNThf2u'; // test
    
    if(password_verify($user_pw, $hash_pw)){
        echo "Correct";
    }
    else{
        echo "Fail";
    }
?>