我试图弄清楚我的加密/解密代码有什么问题,但我似乎在谷歌搜索与我类似的问题时陷入了死胡同。
这是我的两个函数的PHP代码,但我先解释一下。这些工作如何通过使用salt,用户的密码以及他们上次登录的unix纪元时间(或者如果他们之前从未登录过时的当前纪元时间)来创建加密密码。
现在我正在测试代码以查看它是否有效,然后再将其挂钩到我的其余PHP代码中。传递给函数的密码是Test,它使用time()来提供时间,然后在加密过程中将该值存储到全局变量中,这样我就不必在测试时将它存储到数据库中。
在一个SO线程this one中,我在创建IV时使用MCRYPT_RAND读取,然后不保存生成的IV意味着解密将永远不会起作用,因为如果您重新调用mcrypt_create_iv来创建IV将会有所不同解密期间的IV。所以我也为IV制作了全局,并在解密过程中尝试了它,但它仍然没有正确解密。下面的代码反映了这种变化。
//Encrypt the user's password for storing in database
function encrypt($password, $id)
{
echo "Function: encrypt \n"; //For debugging
$salt2 = getTime($id);
$salt1 = 'akey'; //Changed for security purposes
global $cur_iv;
$key = substr(hash('sha256',$salt1.$password.$salt2),0,32);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size,MCRYPT_RAND);
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $password, MCRYPT_MODE_ECB, $iv));
$cur_iv = $iv;
echo $encrypted;
echo "\n";
global $cur_time;
$cur_time = $salt2;
return $encrypted;
}
//Decrypt the user's password for loggin checking
function decrypt($password,$id)
{
echo "Function: decrypt \n"; //For debugging
//$salt2 = getTime($id);
global $cur_time;
$salt2 = $cur_time;
$salt1 = 'akey'; //Changed for security purposes
global $cur_iv;
$key = substr(hash('sha256',$salt1.$password.$salt2),0,32);
$iv = $cur_iv;
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($pass), MCRYPT_MODE_ECB, $iv);
echo $decrypted;
echo "\n";
return $decrypted;
}
加密这是密码的样子:xgr5YB0vHwJAkjkqwTl6rnZMjbZL0qmLE4D8JXDT1rM =
但解密它看起来像这样:NÞÚ±=º)cz_öUñŽP'è8Åáó»d- +ÒAÐ
编辑2:
这是Saikios要求的getTime函数:
//Use the last login time for part of the encryption salt to ensure more secure hashing
function getTime($id)
{
global $sql;
echo "Function: getTime \n"; //For debugging
if ($salt_stmt = $sql->prepare("Select Last_Login From login_log Where User_ID = ?;"))
{
$salt_stmt->bind_param('i',$id);
$salt_stmt->execute();
$salt_stmt->store_result();
$salt_stmt->bind_result($time);
$salt_stmt->fetch();
if ($salt_stmt->num_rows < 1)
{
echo "No last login \n";
$time = time();
}
else
{
echo "Last Login Time: ".$time."\n";
}
return $time;
}
else
{
echo "Error: ".$sql->error;
}
}
答案 0 :(得分:1)
我知道你想使用自己的功能,但为什么不用它作为基础(由Naveen S. Nayak,不是我http://naveensnayak.wordpress.com/2013/03/12/simple-php-encrypt-and-decrypt/),
function encrypt_decrypt($action, $string) {
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = 'This is my secret key';
$secret_iv = 'This is my secret iv';
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
}
else if( $action == 'decrypt' ){
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
$plain_txt = "This is my plain text";
echo "Plain Text = $plain_txt\n";
$encrypted_txt = encrypt_decrypt('encrypt', $plain_txt);
echo "Encrypted Text = $encrypted_txt\n";
$decrypted_txt = encrypt_decrypt('decrypt', $encrypted_txt);
echo "Decrypted Text = $decrypted_txt\n";
if( $plain_txt === $decrypted_txt ) echo "SUCCESS";
else echo "FAILED";
echo "\n";
(关于如何传递变量似乎存在问题)
----- ---------- OLD 我没有getTime函数,但....
加密更改
$cur_time = salt2;
的
$cur_time = $salt2;
答案 1 :(得分:1)
在这里你可以使用我的,但请不要使用md5('密码')作为你的密钥:)
function symEncode($decrypted, $key){
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND);
$iv_base64 = rtrim(base64_encode($iv), '=');
// 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_256, $key, $decrypted . md5($decrypted), MCRYPT_MODE_CBC, $iv));
// We're done!
return $iv_base64 . $encrypted;
}
function symDecode($encrypted, $key){
// Retrieve $iv which is the first 43 characters plus ==, base64_decoded.
$iv = base64_decode(substr($encrypted, 0, 43) . '==');
// Remove $iv from $encrypted.
$encrypted = substr($encrypted, 43);
// 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.
//pre_var_export(debug_backtrace(false));
$decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $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){
die('failed');
}
// Yay!
return $decrypted;
}
$key = md5('password');
$decrypted = 'some important data';
$encrypted = symEncode($decrypted, $key);
echo $encrypted . '<br>';
echo symDecode($encrypted, $key);
输出:
43p2K/0RG20fnuHEx2B3q18KM7FpGLRfb+BwFfYt1V1mMr5PsAroum/jEeO6LonmC4T9N6QQQfOfMwTmbyNRFG4Qi5imGPAq0LsbgYJHWZ50Lw0C7uSRDb7CC1I4Uv1/LFQ==
some important data
和
$key = md5('password');
$decrypted = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc bibendum augue et vehicula adipiscing. Maecenas interdum, enim a accumsan convallis, est urna posuere mauris, eu ultricies lacus enim at justo. Vestibulum auctor sed elit a';
输出:
431nn42sTg7/XlGw4nAw3aFmMiYOnOQCVMjs4xY2m3DNcgiTFyqs1scG3VCxx/srEV9OGePqD4qrV1AectSqIWCSjYCinsS1jThEL9OuxxXeaGCbycXybdeMUCz1gKJZ5zVegMjqcWzyaX6/32sMs+Mh/NO+e9uh9lOdgmpofHEUWc9m4n6yziX2TllDKxbbADogeRjfW5SzzhaR/bx24kV9/44QhMRA1IJwFteHzCI9qTLGL/586MziGUVbZJe9Y9TqhiWEAIgJ0tO0iWVGMBYV1ibwv8VzDr0LcN7qL4345ryoQ3hjrixpLnBNKewKhbCB/4EkJ7+FD1nUyHOZLEyhi52oMqs/uDv1qSk/Pgk+Poku8DCd5ZbxbAJQG6Wp8BlZzfXOak1tyTKaJUsRziM/zmaXvpYrq3WWJti4cQaxc
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc bibendum augue et vehicula adipiscing. Maecenas interdum, enim a accumsan convallis, est urna posuere mauris, eu ultricies lacus enim at justo. Vestibulum auctor sed elit a