ela*_*ick 3 c# cryptography node.js
我正在尝试使用AES192和基于PBKDF2密码/盐的密钥在C#中加密字节数组,并在NodeJS中解密相同的数据.然而,我的密钥生成在NodeJS和C#中产生不同的结果.
C#代码如下:
private void getKeyAndIVFromPasswordAndSalt(string password, byte[] salt, SymmetricAlgorithm symmetricAlgorithm, ref byte[] key, ref byte[] iv)
{
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt);
key = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize / 8);
iv = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize / 8);
}
private byte[] encrypt(byte[] unencryptedBytes, string password, int keySize)
{
RijndaelManaged aesEncryption = new RijndaelManaged();
aesEncryption.KeySize = keySize;
aesEncryption.BlockSize = 128;
byte[] key = new byte[keySize];
byte[] iv = new byte[128];
getKeyAndIVFromPasswordAndSalt(password, Encoding.ASCII.GetBytes("$391Ge3%£2gfR"), aesEncryption, ref key, ref iv);
aesEncryption.Key = key;
aesEncryption.IV = iv;
Console.WriteLine("iv: {0}", Convert.ToBase64String(aesEncryption.IV));
Console.WriteLine("key: {0}", Convert.ToBase64String(aesEncryption.Key));
ICryptoTransform crypto = aesEncryption.CreateEncryptor();
// The result of the encryption and decryption
return crypto.TransformFinalBlock(unencryptedBytes, 0, unencryptedBytes.Length);
}
Run Code Online (Sandbox Code Playgroud)
NodeJS代码如下所示:
crypto.pbkdf2("Test", "$391Ge3%£2gfR", 1000, 192/8, (err, key) => {
var binkey = new Buffer(key, 'ascii');
var biniv = new Buffer("R6taODpFa1/A7WhTZVszvA==", 'base64');
var decipher = crypto.createDecipheriv('aes192', binkey, biniv);
console.log("KEY: " + binkey.toString("base64"));
var decodedLIL = decipher.update(decryptedBuffer);
console.log(decodedLIL);
return;
});
Run Code Online (Sandbox Code Playgroud)
IV是硬编码的,因为我无法弄清楚如何使用pbkdf2来计算它.我查看了nodeJS文档以获得更多帮助,但我不知道这里发生了什么.
任何帮助将不胜感激.
我看到的一个问题是井号(£)的编码.crypto.pbkdf2默认情况下,将密码和salt编码为二进制数组,其中每个字符被截断为最低的8位(意味着井号变为字节0xA3).
但是,您的C#代码将salt转换为ASCII,其中每个字符被截断为最低的7位(意味着井号变为字节0x23).它还使用Rfc2898DeriveBytes构造函数,该构造函数将字符串作为密码.不幸的是,文档没有说明使用什么编码将字符串转换为字节.幸运的是,Rfc2898DeriveBytes确实有另一个构造函数,它接受一个字节数组作为密码,并且还带有一个迭代计数参数,这里是1000.
因此,您应该通过将每个字符截断为8位来将密码和salt字符串转换为字节数组,就像Node.js默认情况下那样.这是一个例子:
var bytes=new byte[password.Length];
for(var i=0;i<bytes.Length;i++){
bytes[i]=(byte)(password[i]&0xFF);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1268 次 |
| 最近记录: |