我在 C# 和 CryptoJS 差异中也有点迷失了。我有两个服务器端 使用AES256位加密数据的函数如下;
public string EncryptText_PBKDF2(string input, string password)
{
// Get the bytes of the strings
byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
// Hash the password with SHA256 for AES key
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] bytesEncrypted = AES_Encrypt_PBKDF2(bytesToBeEncrypted, passwordBytes);
string result = Convert.ToBase64String(bytesEncrypted);
return result;
}
private byte[] AES_Encrypt_PBKDF2(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
byte[] saltBytes = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
using (MemoryStream ms = new MemoryStream())
{
aes.KeySize = 256;
aes.BlockSize = 128;
aes.IV = MD5.Create().ComputeHash(passwordBytes);//16 byte
var PBKDF2_key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
aes.Key = PBKDF2_key.GetBytes(aes.KeySize / 8);//32 byte
aes.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, aes.CreateEncryptor(aes.Key, aes.IV), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
return encryptedBytes;
}
然后我通过控制器操作将其发送给查看;
string res = aesIsl.EncryptText_PBKDF2("my text", "my key");
ViewBag.Crypted1 = res;
在客户端,我从隐藏字段获取它
<div id="crypted"><input id="hidden1" data-enc="@ViewBag.Crypted1" type="hidden" /></div>
并通过crypto-js库对其进行解密(我在上面指出了4次尝试)
这是我的解密功能和尝试:
function AesleDesifrele_PBKDF2(ciphertext, pwd) {
var salt = "0000000000000000";
var iv = CryptoJS.MD5(CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(pwd)));
//these are my attempts to decrypt
//ATTEMPT #1:
//returning object contains a word array but converting it to utf8 string
//causes "Malformed UTF-8 data" error
console.log(CryptoJS.AES.decrypt(ciphertext, pwd).toString(CryptoJS.enc.Utf8));
//ATTEMPT #2
var key = CryptoJS.PBKDF2(
CryptoJS.enc.Utf8.parse(pwd).toString(CryptoJS.enc.Utf8),
CryptoJS.enc.Hex.parse(salt),
{ keySize: 128 / 32, iterations: 1000 }
);
var decrypted = CryptoJS.AES.decrypt(
ciphertext,
key,
{ iv: iv }
);
//returning object contains a word array but converting it to utf8 string
//causes "Malformed UTF-8 data" error
console.log(decrypted.toString(CryptoJS.enc.Utf8));
//ATTEMPT #3
var raw = base64UrlDecode(ciphertext);
var iv1 = CryptoJS.lib.WordArray.create(CryptoJS.MD5(CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(pwd))));;
var salt1 = CryptoJS.lib.WordArray.create(CryptoJS.enc.Hex.parse(salt));
var key1 = generateKey(pwd, salt1);
var ciphertextWords = CryptoJS.lib.WordArray.create(raw.words.slice(128 / 32 + 128 / 32));
var cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: ciphertextWords });
var plaintextArray = CryptoJS.AES.decrypt(
cipherParams,
key1,
{ iv: iv1 }
);
console.log(CryptoJS.enc.Utf8.stringify(plaintextArray));
//returning object contains a word array but converting it to utf8 string
//returns nothing
//ATTEMPT #4
var iv2 = CryptoJS.MD5(CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(pwd)));
var Pass = CryptoJS.enc.Utf8.parse(pwd);
var Salt = CryptoJS.enc.Utf8.parse(salt);
var key256Bits1000Iterations = CryptoJS.PBKDF2(Pass.toString(CryptoJS.enc.Utf8), Salt, { keySize: 256 / 32, iterations: 1000 });
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
});
var decrypted = CryptoJS.AES.decrypt(cipherParams, key256Bits1000Iterations, { mode: CryptoJS.mode.CBC, iv: iv2, padding: CryptoJS.pad.Pkcs7 });
console.log(decrypted.toString(CryptoJS.enc.Utf8));
//returning object contains a word array but converting it to utf8 string
//returns nothing
}
这是为CryptoJs解密生成密钥的函数
function generateKey(secret, salt) {
return CryptoJS.PBKDF2(
secret,
salt,
{
keySize: this.keySize / 32, // size in Words
iterations: 1000,
hasher: CryptoJS.algo.SHA256
}
);
}
这是我使用的转换函数
function base64UrlDecode(str) {
return CryptoJS.enc.Base64.parse(str.replace(/\-/g, '+').replace(/\_/g, '/'));
}
即使我控制客户端上的参数(密文、密码、IV 和盐)与服务器完全相同,CryptoJS.decrypt 没有任何错误返回任何内容。我想我想念为了 C# 将某些东西转换为另一个东西与 CryptoJs 兼容。
欢迎任何建议。
提前致谢。