AES 加密与 C# 解密与 crypto-js [英] AES Encryption with C# Decryption with crypto-js

查看:52
本文介绍了AES 加密与 C# 解密与 crypto-js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm triying to Encrypt string with C# and decrypt it using Angular crypto-js library but it's giving me different output. I tried different c# aes encryption implementations but crypto-js library can't decrypt the encrypted data in c#. Thank you for any help.

这是我的代码

程序.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解密

Simply decrypting it using crypto-js

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

推荐答案

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

The example code is attempting to decrypt the original unencrypted string, which looks to be a mistake perhaps created when trying to simplify the example code for posting the question? Either way the steps required are not too difficult, but the toString() call needs to be replaced.

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

这篇关于AES 加密与 C# 解密与 crypto-js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆