2013-10-29 1 views
10

이전 게시물을 수정했습니다. crypt() 함수를 시도하고 password_hash() 및 password_verify()를 사용하여 데이터베이스에서 오는 암호화 된 비밀번호를 확인하려고 시도했지만 각 호출에서 password_hash() 함수는 다른 암호화 된 문자열을 반환하고 password_verify()는이를 일치시킬 수 없습니다.crypt() 및 password_hash() 함수를 사용하여 암호화 한 후 암호가 일치하지 않습니다.

이것이 내가하는 방법입니다.

//please ignore the syntax error if any 

$data = '11'; 
$dbpass = password_hash($data, PASSWORD_BCRYPT); 
echo $dbpass; // displays the random strings on each page refresh. 

일단 암호가 데이터베이스에 저장되면 로그인 프로세스 중에 일치하지 않습니다. 아래는 내 실제 기능입니다.

private function process_data($password){ 
    $password = __STR.$password.__STR; 
    return password_hash($password, PASSWORD_BCRYPT); 

    } 
    private function processed($login_password, $dbpassword){ 
    $login_password = __STR.$login_password.__STR; 
    return password_verify($login_password, $dbpassword); 
    } 

암호 해시 문자열을 만들기위한 각 함수 호출에서이 함수는 다음에 다른 문자열을 반환합니다.

+0

MD5를 사용하여 암호를 해시하는 이유는 다음과 같습니다. http://www.php.net/manual/en/faq.passwords.php – Tchoupi

+0

나는 더 나은 방법이라고 생각합니다. 각 암호에 고유 한 소금을 제공합니다. – Ethan

+0

당신에게 동의합니다. 나는 MD5 암호화의 반대가 인터넷을 통해 쉽게 이용할 수 있다는 것을 보았습니다. 하지만 해커가이 암호가 무엇인지 파악하기 어렵도록 암호를 추가하려고했습니다. 이게 좋은 생각 아닌가요? 나는 항상 전문가의 견해를 찾는다. –

답변

44

자, 하나씩 살펴 보겠습니다.

먼저 해시이 아닌 암호화입니다. 암호화는 양방향이며 해싱은 한 가지 방법입니다. 해시하고 싶습니다. 우리는 결코 암호화하고 싶지 않습니다. 예, 용어가 중요합니다. 올바른 용어를 사용하십시오.

다음으로 password_hash을 호출 할 때마다이 다른 해시를 반환한다고 가정하면 이라고 가정합니다. 강한 무작위 소금이 나오기 때문입니다. 이것이 어떻게 설계되었으며, 실제로 어떻게 사용해야하는지입니다.

암호 전후에 __STR을 추가하는 "후추"작업을 수행하지 마십시오. 잠재적으로 사용자 암호를 약화시킬뿐입니다 (좋지 않습니다). 그 이유에 대한 자세한 정보는 Read This Answer입니다.

계속 하시겠습니까? 계속해서 crypt을 직접 사용하지 마십시오. 사실 매우 놀랍게 쉽게 망치고 극히 약한 해시를 생성합니다. 이것이 password_* API가 설계된 이유입니다. crypt은 저수준 라이브러리이므로 코드에서 상위 라이브러리를 사용하고자합니다. bcrypt를 망치는 방법에 대한 자세한 내용은 내 블로그 : Seven Ways To Screw Up Bcrypt을 확인하십시오.

암호 API는 간단하고 원 스톱 샵으로 설계되었습니다. 작동하지 않는 경우 다음 사항을 확인하십시오.

  1. PHP> = 5.5.0을 사용하고 있습니까? 또는 password_compat과 함께 PHP> = 5.3.7을 사용하고 있습니까?

    1. 데이터베이스 열의 너비가 충분합니까?

      이상이어야합니다. 60 자 이상이어야합니다.

    2. 기능 결과가 bool(false)이 아닌 문자열인지 확인하고 있습니까?

      내부 오류가있는 경우 password_hash에서 문자열이 아닌 값을 반환합니다.

    3. 오류가 있습니까?

      error_reporting을 최대 설정으로 설정 했습니까? (모든 것을 잡으려면 -1을 권장합니다) 코드에 오류가 없는지 확인 했습니까?

    4. 사용 하시겠습니까?

      function saveUser($username, $password) { 
          $hash = password_hash($password, PASSWORD_BCRYPT); 
          // save $username and $hash to db 
      } 
      function login($username, $password) { 
          // fetch $hash from db 
          return password_verify($password, $hash); 
      } 
      

      각각 한 번만 호출해야합니다.

  2. 당신은 password_compat와 PHP < 5.3.7를 사용하고 있습니까? 그렇다면, 이것이 당신의 문제입니다. 지원되지 않는 버전의 PHP에서 호환성 라이브러리를 사용하고 있습니다. 작동하게 만들 수 있습니다 (특정 RedHat 배포판에서 필요한 수정을 백 포트 했음). 그러나 지원되지 않는 버전을 사용하고 있습니다. 합리적인 릴리스로 업그레이드하십시오.

다른 모든 실패하면,이 코드를 실행하고 결과를 다시보고보십시오 :

$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG'; 
$test = crypt("password", $hash); 
$pass = $test == $hash; 

echo "Test for functionality of compat library: " . ($pass ? "Pass" : "Fail"); 
echo "\n"; 

을 그 Fail을 반환하는 경우, 당신은 PHP의 지원되지 않는 버전을 실행하고 업그레이드해야합니다. 패스가 반환되면 오류가 라이브러리의 어딘가에 있습니다 (라이브러리가 정상적으로 작동 함).

+0

감사합니다. @ircmaxell. saveUser 및 login 기능을 그대로 사용 해본 결과 작동했습니다. 이제 나는 내 웹 사이트에서 이것을 시도 할 것이고 그것이 최종 테스트가 될 것입니다. 나는 그것이 이전에 효과가 없었던 이유를 모른다. 내가 password_hash 및 password_verify 기능을 시도하고 그들을 사용하기 전에 일을 끝낼 수 없습니다. 바라기를 이것들은 내 웹 사이트에서 작동하지 않을 것입니다. 시험하겠습니다. 그리고 다시 연락 드리겠습니다. 감사합니다 –

+1

그것은 남자를 일했습니다. 나는 4 번에서 설명한 기능을 시도했다. 하나님은 당신을 축복 하신다. 건배!! –

+1

@HunzaAli : 듣기 좋게! – ircmaxell

1

암호를 저장하는 가장 좋은 방법은 PHP의 기능 password_hash()을 사용하는 것입니다. 암호마다 암호 학적으로 안전한 소금을 자동으로 생성하여 결과 60 자 문자열에 포함시킵니다. 소금에 대해 전혀 걱정할 필요가 없습니다!

// Hash a new password for storing in the database. 
// The function automatically generates a cryptographically safe salt. 
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT); 

// Check if the hash of the entered login password, matches the stored hash. 
// The salt and the cost factor will be extracted from $existingHashFromDb. 
$isPasswordCorrect = password_verify($password, $existingHashFromDb); 

당신의 자신의 방식은 먼저 너무 빨리 암호 해시를 생성하는 방법이다, 당신은 소금의 목적을 패배 정적 소금을 사용하는 MD5를 사용하는 매우 약하다. 어쩌면 safely storing passwords에 대한 나의 튜토리얼을보고 싶을 것입니다.

편집 업데이트 질문에 대답하기 :

(당신이 후추 더 나은 방법이있다을 추가 할 경우) 암호에 __STR을 추가 할 필요가 없습니다,하지만 예를 들어 기능이 실제로 작동합니다. password_hash()의 반환 값은 무작위 소금 때문에 매번 다를 수 있습니다. 이것은 정확합니다. password_verify() 함수는 확인을 위해이 소금을 추출 할 수 있습니다. 귀하의 경우에는 데이터베이스 필드가 아마도 문제 일 것입니다. 60 자 문자열을 포함 할 수 있는지 확인하십시오.

+0

도움 주셔서 감사합니다. @martinstoeckli. 나는 당신이 글을 편집하기 전에 알아 냈어. 사실 나는 매번 무작위 해시 문자열 시간을 얻는 것에 대해 혼란스러워했다. 그리고 저는 그 사실이 어떻게 검증 될지에 대한 아이디어를 얻지 못했습니다. 하지만 난 알아 냈어,'password_verify()'함수가 이것을 처리한다. 당신의 도움을 주셔서 감사합니다. 건배!! –