암호 암호화에 PHP의 Crypt () 함수를 사용하는 경우 많은 개발자가 이상한 현상을 알 수 있습니다. 때로는 암호화 결과의 길이가 13 자, 때로는 20, 34 또는 그 이상입니다. 이 길이의 불일치로 인해 사람들이 코드에 문제가 있다고 잘못 생각하거나 암호가 잘라 내거나 암호화되어 있다고 쉽게 생각할 수 있습니다. 그래서 무슨 일이 일어나고 있습니까?
PHP의 crypt () 함수는 캡슐화 된 암호화 인터페이스이며 기본 레이어는 운영 체제가 제공하는 암호화 알고리즘에 따라 다릅니다. 이 함수의 첫 번째 매개 변수는 암호화 할 문자열이고 두 번째 매개 변수는 "Salt"입니다. 이 소금 값은 암호화 결과의 고유성에 영향을 줄뿐만 아니라 사용되는 암호화 알고리즘도 결정합니다.
echo crypt("mypassword", "salt");
소금 값을주지 않거나 잘못된 형식을 사용하지 않으면 PHP는 기존 DES (데이터 암호화 표준) 알고리즘과 같은 오래된 암호화 방법으로 자동으로 떨어지므로 출력이 매우 짧으며 일반적으로 13 자에 불과합니다.
crypt () 함수는 여러 알고리즘을 지원하며 다른 알고리즘은 소금 값의 접두사에 의해 결정됩니다. 다음은 몇 가지 일반적인 소금 값 형식과 해당 암호화 알고리즘입니다.
연산 | 소금 가치 형식 | 결과 길이 |
---|---|---|
데스 | 2 자 | 13 자 |
MD5 | $ 1 $ ... | 34 자 |
블로우 피쉬 | $ 2A $ ... / $ 2y $ ... | 60 자 |
SHA-256 | $ 5 $ ... | 43 자 |
SHA-512 | $ 6 $ ... | 86 자 |
따라서 접두사가없는 소금 값을 명시 적으로 전달하지 않거나 형식화되지 않은 소금 값을 통과하지 않으면 PHP는 13 자만 출력하는 Old DES 암호화를 사용하여 돌아올 가능성이 높습니다.
예를 들어:
// 사용 SHA-512 암호화
echo crypt("mypassword", '$6$rounds=5000$usesomesillystring$');
// 출력은 비슷합니다:$6$rounds=5000$usesomesill...(총 길이는 대략 총 길이입니다86)
다음 코드는 기본 DES 알고리즘을 사용합니다.
echo crypt("mypassword", 'sa');
// 출력은 비슷합니다:sahGDf/YwKdl6(오직13캐릭터)
이 문제를 피하려면 항상 명백한 접두사, 바람직하게는 생성 된 임의의 염을 사용하여 소금 값을 사용하고 Blowfish ( $ 2y $ ) 또는 SHA-512 ( $ 6 $ )와 같은보다 안전한 알고리즘을 선택하십시오.
다음과 같은 소금 값을 자동으로 생성 할 수 있습니다.
function generateSalt($algo = 'sha512') {
switch ($algo) {
case 'blowfish':
return '$2y$10$' . substr(str_replace('+', '.', base64_encode(random_bytes(22))), 0, 22);
case 'sha256':
return '$5$' . bin2hex(random_bytes(6));
case 'sha512':
default:
return '$6$' . bin2hex(random_bytes(6));
}
}
$password = 'mypassword';
$salt = generateSalt('sha512');
$hash = crypt($password, $salt);
echo $hash;
<?php
function hashPassword($password) {
$salt = '$2y$10$' . substr(str_replace('+', '.', base64_encode(random_bytes(22))), 0, 22);
return crypt($password, $salt);
}
$plainPassword = '123456';
$hashed = hashPassword($plainPassword);
// 데이터베이스에 저장되었다고 가정합니다
file_put_contents('/var/www/m66.net/passwords.txt', $hashed . PHP_EOL);
// 비밀번호를 확인하십시오
$inputPassword = '123456';
$isValid = crypt($inputPassword, $hashed) === $hashed;
echo $isValid ? '올바른 비밀번호' : '오류 비밀번호';
?>
crypt () 함수를 사용하는 경우 결과의 다른 길이의 기본 원인은 "소금 값"의 형식이 암호화 알고리즘을 결정하기 때문입니다. 암호화 보안 및 일관성을 보장하기 위해 :
항상 올바른 형식의 소금 값으로 명시 적으로 전달하십시오 .
$ 2y $ 또는 $ 6 $ 와 같은 현대적이고 안전한 알고리즘을 선택하십시오 .
기본 동작이나 짧은 소금 형식에 의존하지 마십시오 .
이러한 기본 세부 사항을 이해 한 후 암호 처리에서 숨겨진 보안 위험을 피하고 암호화 로직을보다 제어 가능하고 신뢰할 수있게 할 수 있습니다.