服务端用C#加密数据,客户端用CryptoJS加密的问题

时间:2021-06-04 08:28:04

标签: c# encryption aes cryptojs

我在 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 兼容。

欢迎任何建议。

提前致谢。

0 个答案:

没有答案
相关问题