更新时间:2023-02-17 17:07:15
解密时不使用初始化向量.您需要将初始化向量(IV)与数据一起发送-您的PHP代码永远不会调用 $ aes-> setIV
来自phpseclib,因此它将永远无法解密文本,因为phpseclib如果未设置,将使用全零的IV. RijndaelManaged.GenerateIV
,但是从PBKDF2密钥派生IV显然是可以接受的.PBKDF2(在RFC 2898中指定)是 Rfc2898DeriveBytes
实现的密钥拉伸算法.无论如何,您都需要在PHP端重新生成IV,这是否意味着用加密的数据传输IV(完全没问题)还是在PHP端重新导出IV.
No initialization vector used when decrypting. You need to send the initialization vector (IV) along with the data - your PHP code is never calling $aes->setIV
from phpseclib, so it will never be able to decrypt the text because phpseclib uses an IV of all zeros if one is not set according to the docs. I would personally recommend generating a secure random IV from C# using RijndaelManaged.GenerateIV
, but apparently it's considered acceptable to derive the IV from a PBKDF2 key. PBKDF2 (specified in RFC 2898) is the key-stretching algorithm Rfc2898DeriveBytes
implements. Regardless, you need to re-produce the IV on the PHP side, whether that means transmitting the IV with the encrypted data (which is completely fine) or re-deriving the IV on the PHP side.
使用密码作为盐是一个非常糟糕的想法.盐必须具有足够的长度,并且必须通过密码随机生成.将密码用作盐完全可以消除含盐的问题. MSDN有一些示例代码展示了如何结合使用 Rfc2898DeriveBytes
来生成密码随机盐,但重要的部分在这里:
Using the password as the salt is a REALLY BAD IDEA. The salt needs to be of sufficient length and cryptographically randomly generated. Using the password as the salt completely defeats the point of having a salt. MSDN has some sample code that shows how to generate a cryptographically random salt in conjunction with using Rfc2898DeriveBytes
, but the important part is here:
byte[] saltBytes = new byte[8];
using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider())
{
// Fill the array with a random value.
rngCsp.GetBytes(salt1);
}
setPassword
为此,就像这样:setPassword
to do this, like so:$salt = ...; // get the salt to your PHP code somehow
$iv = ...; // get the IV to your PHP code
$pw = "this_is_my_pw";
$aes = new Crypt_AES(CRYPT_AES_MODE_CBC);
$aes->setPassword($pw, 'pbkdf2' /* key extension algorithm */,
'sha1' /* hash algorithm */, $salt /* generated salt from C# */,
1000 /* number of iterations, must be same as C# code */,
256 / 8 /* key size in bytes, 256 bit key / 8 bits per byte */
);
$aes->setIV($iv);