当我解密用此功能加密的内容时,解密版本与原始版本不同。
class AES256encryption {
var $secret = '';
var $cipher_key = '';
function AES256encryption($secret='') {
if (empty($secret)) {
global $secret;
if (empty($secret)) {
$secret = "some random secret string";
}
}
$this->secret = $secret;
}
function gen_cipher() {
if (empty($this->cipher_key)) {
$this->cipher_key = substr(sha1($this->secret),0,20);
}
}
function mciv() {
return mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND);
}
function encrypt($text) {
$this->gen_cipher();
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, $text, MCRYPT_MODE_CBC, $this->mciv())));
}
function decrypt($text) {
$this->gen_cipher();
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, base64_decode($text), MCRYPT_MODE_CBC, $this->mciv()));
}
}
答案 0 :(得分:4)
每次要加密/解密某些内容时,请勿创建新IV。在加密和解密时需要相同的IV。在CBC模式下,只要它在创建时是随机的,就不需要获得IV秘密。所以你的代码应该是这样的:
class AES256encryption {
var $secret = '';
var $cipher_key = '';
var $mciv = NULL;
function AES256encryption($secret='') {
if (empty($secret)) {
global $secret;⋅⋅⋅⋅⋅⋅⋅⋅⋅
if (empty($secret)) {
$secret = "some random secret string";
}
}
$this->secret = $secret;
$this->gen_mciv();
}
function gen_cipher() {
if (empty($this->cipher_key)) {
$this->cipher_key = substr(sha1($this->secret),0,20);
}
}
function gen_mciv() {
if(NULL === $this->mciv)
{
$this->mciv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND);
}
}
function encrypt($text) {
$this->gen_cipher();
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, $text, MCRYPT_MODE_CBC, $this->mciv)));
}
function decrypt($text) {
$this->gen_cipher();
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, base64_decode($text), MCRYPT_MODE_CBC, $this->mciv));
}
}
$ac = new AES256encryption('my secret pass');
$z = $ac->encrypt('test');
var_dump($z);
$u = $ac->decrypt($z);
var_dump($u);
这似乎有效:
mycroft:~ $ php test_aes.php
string(44) "+KRlfrPp37FfwB4gJXQ67X+8bjbjxEFHjOn55YOgU5o="
string(4) "test"
请检查block cipher modes of operation,然后重新开始这项工作。
答案 1 :(得分:2)
IV需要与加密数据一起发送给收件人。这意味着您的encrypt
函数需要对其进行base64编码并发送,并且您的decrypt
函数需要将其作为输入的一部分接收。
答案 2 :(得分:1)
根据Patrick和caf的帮助,我修改了课程。我发现秘密和IV在解密时必须与加密中使用的相同,否则解密将不起作用。 IV必须是32个字符。这是我修改过的课程,以防任何人使用。
class AES256 {
var $secret = 'some string of any length'; // some random string of any length
var $iv = '0v6bJhPYe2TElCUrT{TD-drLH(5y4pQj'; // must be 32 chars
var $cipher_key = '';
function AES256($secret='', $iv='') {
if (!empty($secret)) {
$this->secret = $secret;
}
$this->cipher_key = substr(sha1($this->secret),0,20);
if (!empty($iv) && (strlen($iv) == 32)) {
$this->iv = $iv;
}
}
function encrypt($plaintext) {
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, $plaintext, MCRYPT_MODE_CBC, $this->iv)));
}
function decrypt($ciphertext) {
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, base64_decode($ciphertext), MCRYPT_MODE_CBC, $this->iv));
}
}
$r = array();
$ac = new AES256('some string of any length');
$r['ciphertext'] = $ac->encrypt(',23ln1gQ6-3ZY[JI');
$r['plaintext'] = $ac->decrypt("wdkUJRR1qxXLkeseVfiLhKnXsAiVzx4H2ytj+2BFRlo=");
print_r($r);