【问题标题】:AES Encryption with C# Decryption with crypto-js使用 C# 进行 AES 加密 使用 crypto-js 进行解密
【发布时间】:2021-11-04 02:50:26
【问题描述】:

我正在尝试使用 C# 加密字符串并使用 Angular crypto-js 库对其进行解密,但它给了我不同的输出。 我尝试了不同的 c# aes 加密实现,但 crypto-js 库无法解密 c# 中的加密数据。感谢您的帮助。

这是我的代码

程序.cs

 static void Main()
    {
        var r = EncryptString("exampleString", "examplePassword");
        Console.Write(r);
    }

 public static string EncryptString(string plainText, string passPhrase)
    {
        if (string.IsNullOrEmpty(plainText))
        {
            return "";
        }
        // generate salt
        byte[] key, iv;
        var salt = new byte[8];
        var rng = new RNGCryptoServiceProvider();
        rng.GetNonZeroBytes(salt);
        DeriveKeyAndIv(passPhrase, salt, out key, out iv);
        // encrypt bytes
        var encryptedBytes = EncryptStringToBytesAes(plainText, key, iv);
        // add salt as first 8 bytes
        var encryptedBytesWithSalt = new byte[salt.Length + encryptedBytes.Length + 8];
        Buffer.BlockCopy(Encoding.ASCII.GetBytes("Salted__"), 0, encryptedBytesWithSalt, 0, 8);
        Buffer.BlockCopy(salt, 0, encryptedBytesWithSalt, 8, salt.Length);
        Buffer.BlockCopy(encryptedBytes, 0, encryptedBytesWithSalt, salt.Length + 8, encryptedBytes.Length);
        // base64 encode
        return Convert.ToBase64String(encryptedBytesWithSalt);
    }
    private static void DeriveKeyAndIv(string passPhrase, byte[] salt, out byte[] key, out byte[] iv)
    {
        // generate key and iv
        var concatenatedHashes = new List<byte>(48);
        var password = Encoding.UTF8.GetBytes(passPhrase);
        var currentHash = new byte[0];
        var md5 = MD5.Create();
        bool enoughBytesForKey = false;
        // See http://www.openssl.org/docs/crypto/EVP_BytesToKey.html#KEY_DERIVATION_ALGORITHM
        while (!enoughBytesForKey)
        {
            var preHashLength = currentHash.Length + password.Length + salt.Length;
            var preHash = new byte[preHashLength];
            Buffer.BlockCopy(currentHash, 0, preHash, 0, currentHash.Length);
            Buffer.BlockCopy(password, 0, preHash, currentHash.Length, password.Length);
            Buffer.BlockCopy(salt, 0, preHash, currentHash.Length + password.Length, salt.Length);
            currentHash = md5.ComputeHash(preHash);
            concatenatedHashes.AddRange(currentHash);
            if (concatenatedHashes.Count >= 48)
                enoughBytesForKey = true;
        }
        key = new byte[32];
        iv = new byte[16];
        concatenatedHashes.CopyTo(0, key, 0, 32);
        concatenatedHashes.CopyTo(32, iv, 0, 16);
        md5.Clear();
    }

    static byte[] EncryptStringToBytesAes(string plainText, byte[] key, byte[] iv)
    {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (key == null || key.Length <= 0)
            throw new ArgumentNullException("key");
        if (iv == null || iv.Length <= 0)
            throw new ArgumentNullException("iv");
        // Declare the stream used to encrypt to an in memory
        // array of bytes.
        MemoryStream msEncrypt;
        // Declare the RijndaelManaged object
        // used to encrypt the data.
        RijndaelManaged aesAlg = null;
        try
        {
            // Create a RijndaelManaged object
            // with the specified key and IV.
            aesAlg = new RijndaelManaged { Mode = CipherMode.CBC, KeySize = 256, BlockSize = 128, Key = key, IV = iv };
            // Create an encryptor to perform the stream transform.
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
            // Create the streams used for encryption.
            msEncrypt = new MemoryStream();
            using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (var swEncrypt = new StreamWriter(csEncrypt))
                {
                    //Write all data to the stream.
                    swEncrypt.Write(plainText);
                    swEncrypt.Flush();
                    swEncrypt.Close();
                }
            }
        }
        finally
        {
            // Clear the RijndaelManaged object.
            aesAlg?.Clear();
        }
        // Return the encrypted bytes from the memory stream.
        return msEncrypt.ToArray();
    }

只需使用 crypto-js 对其进行解密

 let CryptoJS = require('crypto-js');
let r = CryptoJS.AES.decrypt('exampleString', 'examplePassword').toString();

【问题讨论】:

    标签: javascript c# angular encryption


    【解决方案1】:

    示例代码正在尝试解密原始未加密字符串,这看起来可能是在尝试简化示例代码以发布问题时创建的错误?无论哪种方式,所需的步骤都不是太难,但 toString() 调用需要替换。

    var data = "U2FsdGVkX1/Zvh/5BnLfUgfbg5ROSD7Aohumr9asPM8="; // Output from C#
    let r2 = CryptoJS.enc.Utf8.stringify(CryptoJS.AES.decrypt(data, 'examplePassword'));
    console.log(r2);
    

    【讨论】:

    • 非常好。我试图简化代码。谢谢你。现在解密过程成功了。
    猜你喜欢
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 2011-01-31
    相关资源
    最近更新 更多