繁体   English   中英

C#和JS加密方法返回不同的结果

[英]C# & JS encryption methods return different results

我在C#中有旧式加密代码,现在必须在JavaScript中进行相同的加密。 我进行了一些研究,并尝试了3种不同的库,但是无法获得相同的结果。 我使用的最后一个库是CryptoJS,我必须弄清楚为什么我得到不同的结果。

这是两个代码段:

C#代码:

text = "chocolate";

    PasswordHash = "hashhash";
    SaltKey = "saltsaltsaltsa";
    VIKey = "iviviviviviviviv";

    byte[] plainTextBytes = Encoding.UTF8.GetBytes(text);

    byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
    var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
    var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));

    byte[] cipherTextBytes;

    using (var memoryStream = new MemoryStream())
    {
      using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
      {
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
        cryptoStream.FlushFinalBlock();
        cipherTextBytes = memoryStream.ToArray();
        cryptoStream.Close();
      }
      memoryStream.Close();
    }
    var result = Convert.ToBase64String(cipherTextBytes);

结果==>“ 8AbNsyyqHHfi / PEF / bbiew ==”

JavaScript代码:

pass = 'chocolate';
//Creating the Vector Key
var iv = CryptoJS.enc.Utf8.parse('iviviviviviviviv');
//Encoding the Password in from UTF8 to byte array
var passHash = CryptoJS.enc.Utf8.parse('hashhash');
//Encoding the Salt in from UTF8 to byte array
var Salt = CryptoJS.enc.Utf8.parse("saltsaltsaltsa");

//Creating the key in PBKDF2 format to be used during the encryption
var key128Bits1000Iterations = CryptoJS.PBKDF2(passHash, Salt, { keySize: 256 / 8, iterations: 1000 });

//Encrypting the string contained in cipherParams using the PBKDF2 key
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(pass), key128Bits1000Iterations, { mode: CryptoJS.mode.CBC, iv: iv, padding: CryptoJS.pad.ZeroPadding  });
var result = encrypted.ciphertext.toString(CryptoJS.enc.Base64);

结果=“ dpgTA41PDyrM8ef9C1c8iA ==”

问题出在您的PBKDF2盐上。 CryptoJS使用WordArray作为原语来存储盐。 即,一个32位值的数组。 C#使用8位值(显然,它是一个byte数组)。

请注意,在JS中:

var Salt = CryptoJS.lib.WordArray.create([1, 2]);

在C#中与:

byte[] Salt = new byte[] { 0, 0, 0, 1, 0, 0, 0, 2 };

您可以通过在JS中输出以下内容来演示这一点:

var Salt = CryptoJS.lib.WordArray.create([1, 2]);
console.log(Salt.toString(CryptoJS.enc.Base64));
-> AAAAAQAAAAI=

CryptoJS不喜欢将字符串用作盐。 它根本不喜欢它。 无论如何,您都不应该使用字符串或短语作为盐,它应该随机生成并与密码哈希一起存储。

终于找到了解决方案。 感谢Luke Park,他告诉我CryptoJS使用4字节(字)结构。

导致不同结果的问题是密钥大小(显然)不同。 在C#中256/8实际上是32字节长,但是在CryptoJS中,由于使用4字节,所以256/8实际上转换为128字节长:(

一旦我将JS代码段中的密钥大小更改为256/32((256/32)* 4 = 32),它就可以正常工作,并产生与C#加密方法相同的结果。

谢谢大家尼尔

暂无
暂无

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

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