繁体   English   中英

使用 C# 进行 AES 加密 使用 crypto-js 进行解密

[英]AES Encryption with C# Decryption with crypto-js

我正在尝试使用 C# 加密字符串并使用 Angular crypto-js 库对其进行解密,但它给了我不同的 output。 我尝试了不同的 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();

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

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

暂无
暂无

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

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