簡體   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