繁体   English   中英

使用Crypto-JS和C#解密的AES加密-避免“填充无效且无法删除。”

[英]AES encryption with Crypto-JS and C# Decryption - avoiding “Padding is invalid and cannot be removed.”

我正忙于创建一个Javascript应用程序,该应用程序与我们客户的现有C#服务集成在一起。

要求之一是发送AES加密数据,然后将其解密并在服务器上使用。

但是,我无法发送“有效”数据,服务器始终以“填充无效且无法删除”响应。

这是他们的C#加密和解密实现(此设置无法更改,因为它们具有依赖于此的各种子系统:

public static string Encrypt(string input, string password)
    {
        byte[] utfData = Encoding.UTF8.GetBytes(input);
        byte[] saltBytes = Encoding.UTF8.GetBytes(password);
        string encryptedString = string.Empty;
        using (var aes = new AesManaged())
        {
            var rfc = new Rfc2898DeriveBytes(password, saltBytes);

            aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
            aes.KeySize = aes.LegalKeySizes[0].MaxSize;
            aes.Key = rfc.GetBytes(aes.KeySize/8);
            aes.IV = rfc.GetBytes(aes.BlockSize/8);

            using (ICryptoTransform encryptTransform = aes.CreateEncryptor())
            {
                using (var encryptedStream = new MemoryStream())
                {
                    using (var encryptor =
                        new CryptoStream(encryptedStream, encryptTransform, CryptoStreamMode.Write))
                    {
                        encryptor.Write(utfData, 0, utfData.Length);
                        encryptor.Flush();
                        encryptor.Close();

                        byte[] encryptBytes = encryptedStream.ToArray();
                        encryptedString = Convert.ToBase64String(encryptBytes);
                    }
                }
            }
        }
        return encryptedString;
    }


public static string Decrypt(string input, string password)
    {
        byte[] encryptedBytes = Convert.FromBase64String(input);
        byte[] saltBytes = Encoding.UTF8.GetBytes(password);
        string decryptedString = string.Empty;
        using (var aes = new AesManaged())
        {
            var rfc = new Rfc2898DeriveBytes(password, saltBytes);
            aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
            aes.KeySize = aes.LegalKeySizes[0].MaxSize;
            aes.Key = rfc.GetBytes(aes.KeySize/8);
            aes.IV = rfc.GetBytes(aes.BlockSize/8);

            using (ICryptoTransform decryptTransform = aes.CreateDecryptor())
            {
                using (var decryptedStream = new MemoryStream())
                {
                    var decryptor =
                        new CryptoStream(decryptedStream, decryptTransform, CryptoStreamMode.Write);
                    decryptor.Write(encryptedBytes, 0, encryptedBytes.Length);
                    decryptor.Flush();
                    decryptor.Close();

                    byte[] decryptBytes = decryptedStream.ToArray();
                    decryptedString =
                        Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
                }
            }
        }

        return decryptedString;
    }

我正在使用CryptoJS 3.1.2。 例如

var encrypted = CryptoJS.AES.encrypt(input, password).toString();

我如何基本上使用CryptoJS编写等效于其“ Encrypt()”的代码

CryptoJS文档严重缺乏深度,因此很难不知道要期待什么。 很明显,尽管将密码用作盐不是处理盐的安全方法也不是标准方法。 因此,您将必须自己调用PBKDF2函数,创建一个密钥,然后自行IV。 您还需要使用SHA-1(而不是SHA-256)在CryptoJS中创建PBKDF2。 SHA-256似乎是CryptoJS中的默认值-再次未记录-默认值。

唯一的方法是单步执行代码,并比较PBKDF2和AES函数的每个(二进制)值。 请转换为十六进制以进行比较。

暂无
暂无

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

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