2017-05-07 10 views
0

페이지 보안 강화를 위해 노력하고 있으며 일부는 암호화 된 비밀번호로 시작했습니다. password_hash + password verify를 구현하려고하는데, 지금까지 모든 것을 작동시키지 못했습니다. 여기 내 로그인 영역에 있습니다 :PHP password_verify가 데이터베이스에 대해 작동하지 않습니다.

$username = mysqli_real_escape_string($connection, $_POST['username']); 

$password = mysqli_real_escape_string($connection, $_POST['password']); 

$query = "SELECT username, password FROM `users` WHERE username='$username' and user_enabled='1'"; 
$result = mysqli_query($connection, $query) or die(mysqli_error($connection)); 
if($row = mysqli_fetch_assoc($result)) { $dbpassword = $row['password']; } 

if(password_verify($password, $dbpassword)) { 
    echo "Successful login"; 
}else{ 
    echo "Invalid Login Credentials."; 
} 

항상 잘못된 로그인 자격 증명이 있습니다. 나는 사용자의 새 암호를 수정하면

, 내가 뭐하는 거지 다음 데이터베이스에

$pass = mysqli_real_escape_string($connection, $_POST['password']); 
$options = [ 'cost' => 10, 
      'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM), 
      ]; 
$password = password_hash($pass, PASSWORD_BCRYPT, $options)."\n"; 

$query = "UPDATE users 
      SET `password` = '".$password."' 
      WHERE id = ".$_POST['user_id']." 
      "; 

$result = mysqli_query($connection, $query) or die(mysqli_error($connection)); 

암호가 VARCHAR (255)이며,이 같은 것을 저장되어

$2y$10$Y5HIyAsLMfkXIFSJONPsfO3Gxx3b46H.8/WFdLVH3Fqk2XNfy2Uaq 

여기서 내가 뭘 잘못하고 있니?

+0

모든 단계를 디버그하십시오. 'var_dump ($ password)'를 해싱 직후에 데이터베이스에서 체크하고, 데이터베이스에서 꺼낸 후에 확인하십시오. 어떤 단계에서든 변화가 ...? 확인하려는 비밀번호와 동일하게하십시오. – deceze

+2

SQL 주입 빈도가 높은 문자열 연결 대신 준비된 문과 바인딩 된 매개 변수를 사용하는 방법을 배웁니다. – deceze

+0

나는 데이터베이스를 업데이트하기 전에 생성 된 패스워드가 데이터베이스에 저장된 패스워드와 동일하고 로그인 할 때 데이터베이스에서 가져온 패스워드와 동일하다는 것을 확인했다. – cbarg

답변

6

다음 줄의 \n에는 줄 바꿈 (편집 : 사용자가 입력 한 암호에 포함될 수없는 암호)이 포함되어 있습니다.

$password = password_hash($pass, PASSWORD_BCRYPT, $options)."\n"; 

그리고이를 삭제하고 새 해시로 다시 시작해야합니다.

Jay Blanchard 여기에 스택 submitted a note에 대한 회원이 있습니다. password_hash() 설명서에는 너무 길지 않습니다.이 내용은 그와 내가 실제로 이야기 한 내용입니다.

echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";

사람들과 해시를 저장하는 : 해시의 마지막에 개행 문자 \n을 연결 문서, 예로부터 예를 사용하는 경우

하는 것은주의해야합니다 연결 한 개행과 결과적으로 password_verify()은 실패합니다.

또 다른 옵션은 trim()을 사용하는 것입니다; 그것도 작동합니다 (해시의 순간).

$password = password_hash($pass, PASSWORD_BCRYPT, $options)."\n"; 
$password = trim($password); 
// Store in db after 

아직 해시를 지우고 새 해시를 만들어야합니다.

비밀번호를 탈출하지 마세요.

123'\abc (완전히 유효 함) 중 하나는 123\'\abc으로 real_escape_string()으로 수정됩니다. 필요하지 않습니다. password_verify()은 보안 측면에서이를 처리합니다.

+0

와우, 동전 위에! 나는 그 주석을 보지 못했다. 고맙습니다. @Fred -ii- – cbarg

+1

@cbarg 환영합니다. Jay는 그 메모를 너무 오래 전에 제출하지 않았습니다. 그와 나는 메모를 제출하는 것에 대해 이야기 했으므로 그는 앞으로 나아가서 그것을 간과했다. 그것은 종종 간과되는 것이다. http://php.net/manual/en의 매뉴얼에서 [Jay 's note] (http://php.net/manual/en/function.password-hash.php#121017)를 upvote 할 수 있다면 도움이 될 것입니다. /function.password-hash.php - 그 메모는 오래 전에 기한이었고 다른 사람들이 사용자가 작성한 메모를 읽게됩니다. * 건배 * –

+0

개행을 추가하는 경우 데이터베이스의'REPLACE()'가 그것을 수정할 수 있어야합니다. 해시 자체가 정확합니다. – tadman