繁体   English   中英

在CryptoJS中加密和在mCrypt中解密无法正常工作

[英]Encrypting in CryptoJS and decrypting in mCrypt not working properly

在过去的两天里,我一直在为自己的初衷而苦苦挣扎。

我需要一种非常简单且不安全的方式来通过AJAX发送密码并在服务器端对其进行解密

我正在使用来自CryptoJS的 AES:

JS加密

    msg = "message";
    var key = CryptoJS.enc.Hex.parse('000102030405060708090a0b0c0d0e0f');
    var iv  = CryptoJS.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');
    var encrypted = CryptoJS.AES.encrypt(msg, key, { iv: iv });

    var data_base64 = encrypted.ciphertext.toString(CryptoJS.enc.Base64); 
    var iv_base64   = encrypted.iv.toString(CryptoJS.enc.Base64);       
    var key_base64  = encrypted.key.toString(CryptoJS.enc.Base64);

    console.log(data_base64,iv_base64,key_base64) //If I use these keys in the PHP decryption it works

    return encrypted.toString();

...以及使用mCrypt进行 PHP解密

$encrypted = "f82126a59b76d86946a013d9f575d0d4"; //this is what the JS function above returned.
$key = "000102030405060708090a0b0c0d0e0f"; //same key as in JS function
$iv = "101112131415161718191a1b1c1d1e1f"; //same IV as in JS function

$plaintext = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_CBC, $iv ), "\t\0 " );

echo "Original string : " . $encrypted . "<br />\n"; 
echo "Decrypted string : " . $plaintext . "<br />\n";

由于我使用相同的IVkey进行加密,因此我希望这样做可以解密。 但是我似乎缺少了一些东西,因为我仍然在plaintext.看到乱码plaintext.

编辑:

好吧,似乎AES的全部目的是我必须使用的keysIV由CryptoJS输出(请参阅JS函数中的console.log )。 如果使用这些功能,该功能似乎可以正常运行。 但是我实际上并不希望这样做,因为这些键是动态生成的,因此每次我运行JS函数时它们都会更改。 我只需要客户端和服务器之间的共享私钥,该私钥用于加密/解密,并且是静态的。 就如此容易。

您的密钥为128位($ key的长度为32个十六进制字符,表示16字节或128位)。 但是,在mcrypt_decrypt()调用中,您告诉PHP使用带有256位密钥的MCRYPT_RIJNDAEL_256 尝试改用MCRYPT_RIJNDAEL_128 通常,密码应适应所传递密钥的长度,但可能是PHP用空字节填充密钥以使用256位加密。

其次,在PHP中,将mcrypt_decrypt设置为使用CBC模式(请参阅MCRYPT_MODE_CBC )。 您没有指定CryptoJS应该使用哪种模式。 幸运的是,根据CryptoJS的文档,CBC模式是默认使用的一种。 但是,由于您正在编写可移植的代码,因此应考虑将其明确。

编辑

如果它告诉您密钥太长,那是因为您没有打包它们。 您要给PHP一个十六进制编码的长32个字节(256位)的字符串,这不是您的钥匙! 要获取二进制数据,您需要执行以下操作:

$key = pack('H*', "000102030405060708090a0b0c0d0e0f");
$iv = pack('H*', "101112131415161718191a1b1c1d1e1f");

pack('H*', $str); 函数将十六进制表示形式转换为二进制字符串。

MCRYPT_RIJNDAEL_256与AES不同。 256与密码的块大小有关,与密钥大小无关。

快速历史课程-AES是一项竞赛,最终被称为Rijndael的算法所赢得。 Rinjdael是为几种块大小(128、160、192、224和256位)定义的密码。 但是,对于AES,仅选择了128位块大小。

当使用需要IV的模式(例如CBC模式)时,块大小定义IV的大小。 因此,对于AES,无论密钥大小如何,您总是需要128位IV。 支持的密钥大小为128、192或256位。

在PHP中,可以使用密码MCRYPT_RIJNDAEL_128使用AES。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM