2013-08-13 5 views
2

전적으로 혼란스러운 암호화/암호 해독 결과가 있습니다. 암호화하고 나중에 디코딩해야하는 두 개의 다른 문자열이 있는데, 암호화 된 문자열은 그 사이의 MySQL 데이터베이스에 저장됩니다. 이 문자열들 중 첫 번째 문자열은 정상적으로 출력됩니다. 그러나 두 번째 매개 변수는 항상 값 FALSE 인 해독에서 반환됩니다. 필자는 필수적이지 않은 모든 요소를 ​​제거하고 "테스트"라는 일반 텍스트 값을 암호화 루틴에 직접 전달합니다. 다시 말하지만, 첫 번째 것은 올바르게 반환되고 ("test"로) 두 번째 것은 "false"로 반환됩니다.일치하지 않는 암호화/암호 해독 결과

내가 뭘 잘못하고 있는지 알아 내려고 벽에 머리를 세게 치고있어. 두 파일에서 같은 암호와 같은 소금을 사용하고 있습니다. 하나는 작동하지만 두 번째는 작동하지 않을 수 있습니다. ???

한 가지 단서 :이 코드를 단일 PHP 파일에 넣고 데이터베이스를 우회하면 모두 잘 작동합니다. 이것을 어떻게 만들지는 모르지만 적어도 흥미 롭습니다.

다음은 코드입니다. 암호화/복호화 루틴은 mcrypt 용 PHP 사이트의 사용자 게시물에서 가져옵니다. 누구든지 그것을 볼 수 있습니까? 아마 어리석은 짓 일거야.

setValues.php

$encrypted_email_pw = encrypt("test", $password); 
$encrypted_default_pw = encrypt("test", $password); 

$sql = "UPDATE Settings 
     SET email_password='$encrypted_email_pw', 
      default_pw='$encrypted_default_pw' 
     WHERE id='$id'"; 
$result = mysql_query($sql); 

getValues.php

$sql = "SELECT * FROM Settings"; 
$result = mysql_query($sql); 
$row = mysql_fetch_array($result); //there is only one row in this table 

$decrypted_email_pw = decrypt($row['email_password'], $password); 
$decrypted_default_pw = decrypt($row['default_pw'], $password); 

echo $decrypted_email_pw . " | " . $decrypted_default_pw; 
//output: test | false 
die(); 

crypto.php

<?php 

    function encrypt($decrypted, $password, $salt='6rVDB?zKe6batB+k') { 

     // Build a 256-bit $key which is a SHA256 hash of $salt and $password. 
     $key = hash('SHA256', $salt . $password, true); 

     // Build $iv and $iv_base64. 
     // We use a block size of 128 bits (AES compliant) and CBC mode. 
     // (Note: ECB mode is inadequate as IV is not used.) 
     srand(); $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND); 
     if (strlen($iv_base64 = rtrim(base64_encode($iv), '=')) != 22) return false; 

     // Encrypt $decrypted and an MD5 of $decrypted using $key. 
     // MD5 is fine to use here because it's just to verify successful decryption. 
     $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $decrypted . md5($decrypted), MCRYPT_MODE_CBC, $iv)); 

     // We're done! 
     return $iv_base64 . $encrypted; 
    } 

    function decrypt($encrypted, $password, $salt='6rVDB?zKe6batB+k') { 

     // Build a 256-bit $key which is a SHA256 hash of $salt and $password. 
     $key = hash('SHA256', $salt . $password, true); 

     // Retrieve $iv which is the first 22 characters plus ==, base64_decoded. 
     $iv = base64_decode(substr($encrypted, 0, 22) . '=='); 

     // Remove $iv from $encrypted. 
     $encrypted = substr($encrypted, 22); 

     // Decrypt the data. 
     // rtrim won't corrupt the data because the last 32 characters are the md5 hash; 
     // thus any \0 character has to be padding. 
     $decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($encrypted), MCRYPT_MODE_CBC, $iv), "\0\4"); 

     // Retrieve $hash which is the last 32 characters of $decrypted. 
     $hash = substr($decrypted, -32); 

     // Remove the last 32 characters from $decrypted. 
     $decrypted = substr($decrypted, 0, -32); 

     // Integrity check. If this fails, either the data is corrupted, or the password/salt was incorrect. 
     if (md5($decrypted) != $hash) return false; 

     return $decrypted; 
    } 

?> 
+0

고정 소금을 사용하지 마십시오. – SLaks

+0

이것이 일관성없는 결과를 설명한다고 말하는가? – Alex

+0

먼저 데이터베이스 단계를 건너 뛰고 대신 SQL 또는 다른 곳으로 전달하지 않고 스크립트 자체에서 암호화에서 암호 해독으로 데이터를 전달하려고합니다. 그것은 사소한 것처럼 보이지만 먼저 데이터베이스가 결과에 영향을 주는지 또는 암호화 라이브러리 자체의 처리에 문제가 있는지를 알아야합니다. – BrianHall

답변

2

당신이 설정 테이블의 두 열을 확인 했습니까? 그들은 동일한 데이터 유형을 가지고 있습니까? 그리고 encrypt() 및 decrypt() 메서드가 제대로 작동합니까?

이 작업을 마친 후에는 각 암호에 무작위로 생성 된 소금을 사용하고 암호와 함께 테이블에 소금을 저장하는 것이 좋습니다.

+0

그게 전부 였어. 내 열 중 하나가 varchar (100)이고 다른 하나가 varchar (50)이었습니다. 감사! – Alex

+0

이것은 매우 흥미로운 결과이며, 나는 예상하지 못했던 결과입니다. 질문과 답변 모두 upvote를 제공! – Floris

관련 문제