在 C# 中使用 AES 加密

Posted

技术标签:

【中文标题】在 C# 中使用 AES 加密【英文标题】:Using AES encryption in C# 【发布时间】:2010-09-21 08:50:13 【问题描述】:

我似乎找不到使用 AES 128 位加密的干净示例。

有人有示例代码吗?

【问题讨论】:

这篇文章不错:codeproject.com/Articles/769741/… 【参考方案1】:

如果您只想使用内置加密提供程序 RijndaelManaged,请查看以下帮助文章(它还有一个简单的代码示例):

http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged.aspx

以防万一您急需样品,这里是抄袭的荣耀:

using System;
using System.IO;
using System.Security.Cryptography;

namespace RijndaelManaged_Example

    class RijndaelExample
    
        public static void Main()
        
            try
            

                string original = "Here is some data to encrypt!";

                // Create a new instance of the RijndaelManaged 
                // class.  This generates a new key and initialization  
                // vector (IV). 
                using (RijndaelManaged myRijndael = new RijndaelManaged())
                

                    myRijndael.GenerateKey();
                    myRijndael.GenerateIV();
                    // Encrypt the string to an array of bytes. 
                    byte[] encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);

                    // Decrypt the bytes to a string. 
                    string roundtrip = DecryptStringFromBytes(encrypted, myRijndael.Key, myRijndael.IV);

                    //Display the original data and the decrypted data.
                    Console.WriteLine("Original:   0", original);
                    Console.WriteLine("Round Trip: 0", roundtrip);
                

            
            catch (Exception e)
            
                Console.WriteLine("Error: 0", e.Message);
            
        
        static byte[] EncryptStringToBytes(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");
            byte[] encrypted;
            // Create an RijndaelManaged object 
            // with the specified key and IV. 
            using (RijndaelManaged rijAlg = new RijndaelManaged())
            
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decryptor to perform the stream transform.
                ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for encryption. 
                using (MemoryStream msEncrypt = new MemoryStream())
                
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        

                            //Write all data to the stream.
                            swEncrypt.Write(plainText);
                        
                        encrypted = msEncrypt.ToArray();
                    
                
            


            // Return the encrypted bytes from the memory stream. 
            return encrypted;

        

        static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
        
            // Check arguments. 
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");

            // Declare the string used to hold 
            // the decrypted text. 
            string plaintext = null;

            // Create an RijndaelManaged object 
            // with the specified key and IV. 
            using (RijndaelManaged rijAlg = new RijndaelManaged())
            
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for decryption. 
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        

                            // Read the decrypted bytes from the decrypting stream 
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                        
                    
                

            

            return plaintext;

        
    

【讨论】:

您的代码没有将IV与密文一起存储,因此很难正确使用,并且容易被滥用。 IV 不是辅助密钥,它应该为每次加密随机生成,并与密文一起存储。 对于未来的读者:我已经使用 MSDN 上示例的更新代码更新了此处的代码示例 另外:不要忘记你很可能在密码学方面很糟糕。 happybearsoftware.com/… 当然可以。 msdn.microsoft.com/de-de/library/…看备注。您可以使用 rijndael,但在更改设置时可能会导致兼容性问题。因此,如果您想使用 AES(FIPS-197) 加密,我会使用 Aes-Class @EricJ。 using () 块自动处理 myRijndael 对象(以及本示例中的所有其他 RijndaelManaged 对象)。也许您的评论是针对较早版本的答案,或者链接显示了不好的示例,但今天情况并非如此。【参考方案2】:

我最近不得不在我自己的项目中再次遇到这个问题 - 我想分享我一直在使用的更简单的代码,因为这个问题和一系列答案不断出现在我的搜索中。

我不会讨论关于更新频率的安全问题,例如您的 SaltInitialization Vector - 这是一个安全论坛的主题,并且有一些很棒的资源可供查看。这只是在 C# 中实现AesManaged 的代码块。

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Your.Namespace.Security 
    public static class Cryptography 
        #region Settings

        private static int _iterations = 2;
        private static int _keySize = 256;

        private static string _hash     = "SHA1";
        private static string _salt     = "aselrias38490a32"; // Random
        private static string _vector   = "8947az34awl34kjq"; // Random

        #endregion

        public static string Encrypt(string value, string password) 
            return Encrypt<AesManaged>(value, password);
        
        public static string Encrypt<T>(string value, string password) 
                where T : SymmetricAlgorithm, new() 
            byte[] vectorBytes = GetBytes<ASCIIEncoding>(_vector);
            byte[] saltBytes = GetBytes<ASCIIEncoding>(_salt);
            byte[] valueBytes = GetBytes<UTF8Encoding>(value);

            byte[] encrypted;
            using (T cipher = new T()) 
                PasswordDeriveBytes _passwordBytes = 
                    new PasswordDeriveBytes(password, saltBytes, _hash, _iterations);
                byte[] keyBytes = _passwordBytes.GetBytes(_keySize / 8);

                cipher.Mode = CipherMode.CBC;

                using (ICryptoTransform encryptor = cipher.CreateEncryptor(keyBytes, vectorBytes)) 
                    using (MemoryStream to = new MemoryStream()) 
                        using (CryptoStream writer = new CryptoStream(to, encryptor, CryptoStreamMode.Write)) 
                            writer.Write(valueBytes, 0, valueBytes.Length);
                            writer.FlushFinalBlock();
                            encrypted = to.ToArray();
                        
                    
                
                cipher.Clear();
            
            return Convert.ToBase64String(encrypted);
        

        public static string Decrypt(string value, string password) 
            return Decrypt<AesManaged>(value, password);
        
        public static string Decrypt<T>(string value, string password) where T : SymmetricAlgorithm, new() 
            byte[] vectorBytes = GetBytes<ASCIIEncoding>(_vector);
            byte[] saltBytes = GetBytes<ASCIIEncoding>(_salt);
            byte[] valueBytes = Convert.FromBase64String(value);

            byte[] decrypted;
            int decryptedByteCount = 0;

            using (T cipher = new T()) 
                PasswordDeriveBytes _passwordBytes = new PasswordDeriveBytes(password, saltBytes, _hash, _iterations);
                byte[] keyBytes = _passwordBytes.GetBytes(_keySize / 8);

                cipher.Mode = CipherMode.CBC;

                try 
                    using (ICryptoTransform decryptor = cipher.CreateDecryptor(keyBytes, vectorBytes)) 
                        using (MemoryStream from = new MemoryStream(valueBytes)) 
                            using (CryptoStream reader = new CryptoStream(from, decryptor, CryptoStreamMode.Read)) 
                                decrypted = new byte[valueBytes.Length];
                                decryptedByteCount = reader.Read(decrypted, 0, decrypted.Length);
                            
                        
                    
                 catch (Exception ex) 
                    return String.Empty;
                

                cipher.Clear();
            
            return Encoding.UTF8.GetString(decrypted, 0, decryptedByteCount);
        

    

代码使用起来非常简单。它实际上只需要以下内容:

string encrypted = Cryptography.Encrypt(data, "testpass");
string decrypted = Cryptography.Decrypt(encrypted, "testpass");

默认情况下,实现使用 AesManaged - 但您实际上也可以插入任何其他 SymmetricAlgorithm。 .NET 4.5 的可用SymmetricAlgorithm 继承者列表可在以下位置找到:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.symmetricalgorithm.aspx

截至发文时,当前名单包括:

AesManaged RijndaelManaged DESCryptoServiceProvider RC2CryptoServiceProvider TripleDESCryptoServiceProvider

要在上面的代码中使用RijndaelManaged,例如,您可以使用:

string encrypted = Cryptography.Encrypt<RijndaelManaged>(dataToEncrypt, password);
string decrypted = Cryptography.Decrypt<RijndaelManaged>(encrypted, password);

我希望这对那里的人有所帮助。

【讨论】:

我收到以下错误:“错误名称 'GetBytes' 在当前上下文中不存在。”我该如何解决这个问题?编辑:通过使用 ASCIIEncoding.ASCII.GetBytes 和 UTF8Encoding.UTF8.GetBytes 修复它。 恐怕不是,@DeveloperX。该代码依赖于 .NET Cryptography 库,所以我的猜测是,您要么必须在 Java 中找到一组等效的库,要么自行开发。 :( 嗨,特洛伊,我也有和 cvocvo 说的一样的问题。消息是The name 'GetBytes' does not exist in the current context。请问您使用的是哪个版本的 .Net 框架? 您的代码错误,在 Decrypt 中将“valuebytes”行更改为以下内容:` byte[] valueBytes = Convert.FromBase64String(value);` 。这样做的原因是因为在 Encrypt 中你转换了 ToBase64,所以现在你需要在 Decrypt 中 ConvertFromBase64String,否则你会得到无效长度错误。 更新 IV 是 每条 消息,而不是辩论,只是简单说明您如何使用 AES-CBC,这个答案完全是错误的。【参考方案3】:

看这里的样本..

http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=VS.100).aspx#Y2262

MSDN上的例子不能正常运行(出现错误),因为Initial Vector(iv)Key没有没有初始值 >。我添加了 2 行代码,现在可以正常工作了。

更多详情见下文:

using System.Windows.Forms;
using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace AES_TESTER

   public partial class Form1 : Form
   
       public Form1()
       
          InitializeComponent();
       

       private void Form1_Load(object sender, EventArgs e)
       
          try
          

            string original = "Here is some data to encrypt!";
            MessageBox.Show("Original:   " + original);

            // Create a new instance of the RijndaelManaged
            // class.  This generates a new key and initialization 
            // vector (IV).
            using (RijndaelManaged myRijndael = new RijndaelManaged())
            
                 myRijndael.GenerateKey();
                 myRijndael.GenerateIV();

                // Encrypt the string to an array of bytes.
                byte[] encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);

                StringBuilder s = new StringBuilder();
                foreach (byte item in encrypted)
                
                   s.Append(item.ToString("X2") + " ");
                
                MessageBox.Show("Encrypted:   " + s);

                // Decrypt the bytes to a string.
                string decrypted = DecryptStringFromBytes(encrypted, myRijndael.Key, myRijndael.IV);

                //Display the original data and the decrypted data.
                MessageBox.Show("Decrypted:    " + decrypted);
            

        
        catch (Exception ex)
        
            MessageBox.Show("Error: 0", ex.Message);
        
    

    static byte[] EncryptStringToBytes(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("Key");
        byte[] encrypted;
        // Create an RijndaelManaged object
        // with the specified key and IV.
        using (RijndaelManaged rijAlg = new RijndaelManaged())
        
            rijAlg.Key = Key;
            rijAlg.IV = IV;
            rijAlg.Mode = CipherMode.CBC;
            rijAlg.Padding = PaddingMode.Zeros;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

            // Create the streams used for encryption.
            using (MemoryStream msEncrypt = new MemoryStream())
            
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    

                        //Write all data to the stream.
                        swEncrypt.Write(plainText);
                    
                    encrypted = msEncrypt.ToArray();
                
            
        


        // Return the encrypted bytes from the memory stream.
        return encrypted;

    

    static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
    
        // Check arguments.
        if (cipherText == null || cipherText.Length <= 0)
            throw new ArgumentNullException("cipherText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");

        // Declare the string used to hold
        // the decrypted text.
        string plaintext = null;

        // Create an RijndaelManaged object
        // with the specified key and IV.
        using (RijndaelManaged rijAlg = new RijndaelManaged())
        
            rijAlg.Key = Key;
            rijAlg.IV = IV;
            rijAlg.Mode = CipherMode.CBC;
            rijAlg.Padding = PaddingMode.Zeros;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

            // Create the streams used for decryption.
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    

                        // Read the decrypted bytes from the decrypting stream
                        // and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                    
                
            

        

        return plaintext;
     
   

【讨论】:

在调用函数加密和解密之前不要忘记设置初始向量的值和密钥,使用此行代码:myRijndael.GenerateKey(); myRijndael.GenerateIV(); 您可以通过更改此行代码来更改 AES 模式 rijAlg.Mode = CipherMode.CBC;例如 rijAlg.Mode = CipherMode.CFB;或 rijAlg.Mode = CipherMode.ECB;如果您想测试 AES,请查看 [link] inconteam.com/software-development/41-encryption/…,它是否正常运行。【参考方案4】:

使用 AES 还是实施 AES?要使用 AES,有 System.Security.Cryptography.RijndaelManaged 类。

【讨论】:

是的,我明白,但我似乎无法弄清楚如何以 32 个字符作为键(半字节)来实现 128 位 CFB。你知道如何编辑上面的代码吗?我只是开始了。似乎需要更多帮助【参考方案5】:

有关除 AES 加密之外执行密钥派生的更完整示例,请参阅Getting AES encryption to work across javascript and C# 中发布的答案和链接。

编辑 附注:Javascript Cryptography considered harmful. 值得一读。

【讨论】:

【参考方案6】:
//Code to encrypt Data :   
 public byte[] encryptdata(byte[] bytearraytoencrypt, string key, string iv)  
           
           AesCryptoServiceProvider dataencrypt = new AesCryptoServiceProvider();  
           //Block size : Gets or sets the block size, in bits, of the cryptographic operation.  
           dataencrypt.BlockSize = 128;  
           //KeySize: Gets or sets the size, in bits, of the secret key  
           dataencrypt.KeySize = 128;  
           //Key: Gets or sets the symmetric key that is used for encryption and decryption.  
           dataencrypt.Key = System.Text.Encoding.UTF8.GetBytes(key);  
           //IV : Gets or sets the initialization vector (IV) for the symmetric algorithm  
           dataencrypt.IV = System.Text.Encoding.UTF8.GetBytes(iv);  
           //Padding: Gets or sets the padding mode used in the symmetric algorithm  
           dataencrypt.Padding = PaddingMode.PKCS7;  
           //Mode: Gets or sets the mode for operation of the symmetric algorithm  
           dataencrypt.Mode = CipherMode.CBC;  
           //Creates a symmetric AES encryptor object using the current key and initialization vector (IV).  
           ICryptoTransform crypto1 = dataencrypt.CreateEncryptor(dataencrypt.Key, dataencrypt.IV);  
           //TransformFinalBlock is a special function for transforming the last block or a partial block in the stream.   
           //It returns a new array that contains the remaining transformed bytes. A new array is returned, because the amount of   
           //information returned at the end might be larger than a single block when padding is added.  
           byte[] encrypteddata = crypto1.TransformFinalBlock(bytearraytoencrypt, 0, bytearraytoencrypt.Length);  
           crypto1.Dispose();  
           //return the encrypted data  
           return encrypteddata;  
           

//code to decrypt data
    private byte[] decryptdata(byte[] bytearraytodecrypt, string key, string iv)  
       

       AesCryptoServiceProvider keydecrypt = new AesCryptoServiceProvider();  
       keydecrypt.BlockSize = 128;  
       keydecrypt.KeySize = 128;  
       keydecrypt.Key = System.Text.Encoding.UTF8.GetBytes(key);  
       keydecrypt.IV = System.Text.Encoding.UTF8.GetBytes(iv);  
       keydecrypt.Padding = PaddingMode.PKCS7;  
       keydecrypt.Mode = CipherMode.CBC;  
       ICryptoTransform crypto1 = keydecrypt.CreateDecryptor(keydecrypt.Key, keydecrypt.IV);  

       byte[] returnbytearray = crypto1.TransformFinalBlock(bytearraytodecrypt, 0, bytearraytodecrypt.Length);  
       crypto1.Dispose();  
       return returnbytearray;  
     

【讨论】:

当心:我看到缺少 Dispose() 语句。 您好!在其他选择上使用 PKCS7 填充有什么特别的原因吗?从我读到的内容来看,它不如 OAEP 填充,由于某种原因,它对 AES 不可用。 PKCS7 在 AES 中是否比在 RSA 中更安全?【参考方案7】:

http://www.codeproject.com/Articles/769741/Csharp-AES-bits-Encryption-Library-with-Salt

using System.Security.Cryptography;
using System.IO;

 

public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)

    byte[] encryptedBytes = null;
    byte[] saltBytes = new byte[]  1, 2, 3, 4, 5, 6, 7, 8 ;
    using (MemoryStream ms = new MemoryStream())
    
        using (RijndaelManaged AES = new RijndaelManaged())
        
            AES.KeySize = 256;
            AES.BlockSize = 128;
            var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
            AES.Key = key.GetBytes(AES.KeySize / 8);
            AES.IV = key.GetBytes(AES.BlockSize / 8);
            AES.Mode = CipherMode.CBC;
            using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
            
                cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                cs.Close();
            
            encryptedBytes = ms.ToArray();
        
    
    return encryptedBytes;


public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)

    byte[] decryptedBytes = null;
    byte[] saltBytes = new byte[]  1, 2, 3, 4, 5, 6, 7, 8 ;
    using (MemoryStream ms = new MemoryStream())
    
        using (RijndaelManaged AES = new RijndaelManaged())
        
            AES.KeySize = 256;
            AES.BlockSize = 128;
            var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
            AES.Key = key.GetBytes(AES.KeySize / 8);
            AES.IV = key.GetBytes(AES.BlockSize / 8);
            AES.Mode = CipherMode.CBC;
            using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
            
                cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                cs.Close();
            
            decryptedBytes = ms.ToArray();
        
    
    return decryptedBytes;

【讨论】:

这篇文章对我很有帮助,但要注意这是最基本的代码。在文章中,它展示了如何将盐添加到密文中并使用 SecureString 等。【参考方案8】:

试试这个代码,也许有用。 1.新建C#项目,在Form1中添加如下代码:

using System;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace ExampleCrypto

    public partial class Form1 : Form
    
        public Form1()
        
            InitializeComponent();
        

        private void Form1_Load(object sender, EventArgs e)
        
            string strOriginalData = string.Empty;
            string strEncryptedData = string.Empty;
            string strDecryptedData = string.Empty;

            strOriginalData = "this is original data 1234567890"; // your original data in here
            MessageBox.Show("ORIGINAL DATA:\r\n" + strOriginalData);

            clsCrypto aes = new clsCrypto();
            aes.IV = "this is your IV";     // your IV
            aes.KEY = "this is your KEY";    // your KEY      
            strEncryptedData = aes.Encrypt(strOriginalData, CipherMode.CBC);    // your cipher mode
            MessageBox.Show("ENCRYPTED DATA:\r\n" + strEncryptedData);

            strDecryptedData = aes.Decrypt(strEncryptedData, CipherMode.CBC);
            MessageBox.Show("DECRYPTED DATA:\r\n" + strDecryptedData);
        

    

2.创建 clsCrypto.cs 并在您的课程中复制粘贴以下代码并运行您的代码。我用MD5生成了初始向量(IV)和AES的KEY。

using System;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Remoting.Metadata.W3cXsd2001;

namespace ExampleCrypto

    public class clsCrypto
    
        private string _KEY = string.Empty;
        protected internal string KEY
        
            get
            
                return _KEY;
            
            set
            
                if (!string.IsNullOrEmpty(value))
                
                    _KEY = value;
                
            
        

        private string _IV = string.Empty;
        protected internal string IV
        
            get
            
                return _IV;
            
            set
            
                if (!string.IsNullOrEmpty(value))
                
                    _IV = value;
                
            
        

        private string CalcMD5(string strInput)
        
            string strOutput = string.Empty;
            if (!string.IsNullOrEmpty(strInput))
            
                try
                
                    StringBuilder strHex = new StringBuilder();
                    using (MD5 md5 = MD5.Create())
                    
                        byte[] bytArText = Encoding.Default.GetBytes(strInput);
                        byte[] bytArHash = md5.ComputeHash(bytArText);
                        for (int i = 0; i < bytArHash.Length; i++)
                        
                            strHex.Append(bytArHash[i].ToString("X2"));
                        
                        strOutput = strHex.ToString();
                    
                
                catch (Exception ex)
                
                    MessageBox.Show(ex.Message);
                
            
            return strOutput;
        

        private byte[] GetBytesFromHexString(string strInput)
        
            byte[] bytArOutput = new byte[]  ;
            if ((!string.IsNullOrEmpty(strInput)) && strInput.Length % 2 == 0)
            
                SoapHexBinary hexBinary = null;
                try
                
                    hexBinary = SoapHexBinary.Parse(strInput);
                
                catch (Exception ex)
                
                    MessageBox.Show(ex.Message);
                
                bytArOutput = hexBinary.Value;
            
            return bytArOutput;
        

        private byte[] GenerateIV()
        
            byte[] bytArOutput = new byte[]  ;
            try
            
                string strIV = CalcMD5(IV);
                bytArOutput = GetBytesFromHexString(strIV);
            
            catch (Exception ex)
            
                MessageBox.Show(ex.Message);
            
            return bytArOutput;
        

        private byte[] GenerateKey()
        
            byte[] bytArOutput = new byte[]  ;
            try
            
                string strKey = CalcMD5(KEY);
                bytArOutput = GetBytesFromHexString(strKey);
            
            catch (Exception ex)
            
                MessageBox.Show(ex.Message);
            
            return bytArOutput;
        

        protected internal string Encrypt(string strInput, CipherMode cipherMode)
        
            string strOutput = string.Empty;
            if (!string.IsNullOrEmpty(strInput))
            
                try
                
                    byte[] bytePlainText = Encoding.Default.GetBytes(strInput);
                    using (RijndaelManaged rijManaged = new RijndaelManaged())
                    
                        rijManaged.Mode = cipherMode;
                        rijManaged.BlockSize = 128;
                        rijManaged.KeySize = 128;
                        rijManaged.IV = GenerateIV();
                        rijManaged.Key = GenerateKey();
                        rijManaged.Padding = PaddingMode.Zeros;
                        ICryptoTransform icpoTransform = rijManaged.CreateEncryptor(rijManaged.Key, rijManaged.IV);
                        using (MemoryStream memStream = new MemoryStream())
                        
                            using (CryptoStream cpoStream = new CryptoStream(memStream, icpoTransform, CryptoStreamMode.Write))
                            
                                cpoStream.Write(bytePlainText, 0, bytePlainText.Length);
                                cpoStream.FlushFinalBlock();
                            
                            strOutput = Encoding.Default.GetString(memStream.ToArray());
                        
                    
                
                catch (Exception ex)
                
                    MessageBox.Show(ex.Message);
                
            
            return strOutput;
        

        protected internal string Decrypt(string strInput, CipherMode cipherMode)
        
            string strOutput = string.Empty;
            if (!string.IsNullOrEmpty(strInput))
            
                try
                
                    byte[] byteCipherText = Encoding.Default.GetBytes(strInput);
                    byte[] byteBuffer = new byte[strInput.Length];
                    using (RijndaelManaged rijManaged = new RijndaelManaged())
                    
                        rijManaged.Mode = cipherMode;
                        rijManaged.BlockSize = 128;
                        rijManaged.KeySize = 128;
                        rijManaged.IV = GenerateIV();
                        rijManaged.Key = GenerateKey();
                        rijManaged.Padding = PaddingMode.Zeros;
                        ICryptoTransform icpoTransform = rijManaged.CreateDecryptor(rijManaged.Key, rijManaged.IV);
                        using (MemoryStream memStream = new MemoryStream(byteCipherText))
                        
                            using (CryptoStream cpoStream = new CryptoStream(memStream, icpoTransform, CryptoStreamMode.Read))
                            
                                cpoStream.Read(byteBuffer, 0, byteBuffer.Length);
                            
                            strOutput = Encoding.Default.GetString(byteBuffer);
                        
                    
                
                catch (Exception ex)
                
                    MessageBox.Show(ex.Message);
                
            
            return strOutput;
        

    

【讨论】:

【参考方案9】:

您可以使用文本框中的密码,例如密钥... 使用此代码,您可以加密/解密文本、图片、word 文档、pdf....

 public class Rijndael

    private byte[] key;
    private readonly byte[] vector =  255, 64, 191, 111, 23, 3, 113, 119, 231, 121, 252, 112, 79, 32, 114, 156 ;

    ICryptoTransform EnkValue, DekValue;

    public Rijndael(byte[] key)
    
        this.key = key;
        RijndaelManaged rm = new RijndaelManaged();
        rm.Padding = PaddingMode.PKCS7;
        EnkValue = rm.CreateEncryptor(key, vector);
        DekValue = rm.CreateDecryptor(key, vector);
    

    public byte[] Encrypt(byte[] byte)
    

        byte[] enkByte= byte;
        byte[] enkNewByte;
        using (MemoryStream ms = new MemoryStream())
        
            using (CryptoStream cs = new CryptoStream(ms, EnkValue, CryptoStreamMode.Write))
            
                cs.Write(enkByte, 0, enkByte.Length);
                cs.FlushFinalBlock();

                ms.Position = 0;
                enkNewByte= new byte[ms.Length];
                ms.Read(enkNewByte, 0, enkNewByte.Length);
            
        
        return enkNeyByte;
    

    public byte[] Dekrypt(byte[] enkByte)
    
        byte[] dekByte;
        using (MemoryStream ms = new MemoryStream())
        
            using (CryptoStream cs = new CryptoStream(ms, DekValue, CryptoStreamMode.Write))
            
                cs.Write(enkByte, 0, enkByte.Length);
                cs.FlushFinalBlock();

                ms.Position = 0;
                dekByte= new byte[ms.Length];
                ms.Read(dekByte, 0, dekByte.Length);
            
        
        return dekByte;
    

将密码从文本框转换为字节数组...

private byte[] ConvertPasswordToByte(string password)
    
        byte[] key = new byte[32];
        for (int i = 0; i < passwprd.Length; i++)
        
            key[i] = Convert.ToByte(passwprd[i]);
        
        return key;
    

【讨论】:

如果密码超过 32 个字符,ConvertPasswordToByte 中可能会出现 IndexOutOfRangeException。 您的 IV 应该是随机的,并与密码文本一起存储(但未加密)。【参考方案10】:

这是一个简洁的代码,用于理解用 C# 实现的 AES 256 算法 调用加密函数为encryptedstring = cryptObj.Encrypt(username, "AGARAMUDHALA", "EZHUTHELLAM", "SHA1", 3, "@1B2c3D4e5F6g7H8", 256);

public class Crypt

    public string Encrypt(string passtext, string passPhrase, string saltV, string hashstring, int Iterations, string initVect, int keysize)
    
        string functionReturnValue = null;
        // Convert strings into byte arrays.
        // Let us assume that strings only contain ASCII codes.
        // If strings include Unicode characters, use Unicode, UTF7, or UTF8
        // encoding.
        byte[] initVectorBytes = null;
        initVectorBytes = Encoding.ASCII.GetBytes(initVect);
        byte[] saltValueBytes = null;
        saltValueBytes = Encoding.ASCII.GetBytes(saltV);

        // Convert our plaintext into a byte array.
        // Let us assume that plaintext contains UTF8-encoded characters.
        byte[] plainTextBytes = null;
        plainTextBytes = Encoding.UTF8.GetBytes(passtext);
        // First, we must create a password, from which the key will be derived.
        // This password will be generated from the specified passphrase and
        // salt value. The password will be created using the specified hash
        // algorithm. Password creation can be done in several iterations.
        PasswordDeriveBytes password = default(PasswordDeriveBytes);
        password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashstring, Iterations);
        // Use the password to generate pseudo-random bytes for the encryption
        // key. Specify the size of the key in bytes (instead of bits).
        byte[] keyBytes = null;
        keyBytes = password.GetBytes(keysize/8);
        // Create uninitialized Rijndael encryption object.
        RijndaelManaged symmetricKey = default(RijndaelManaged);
        symmetricKey = new RijndaelManaged();

        // It is reasonable to set encryption mode to Cipher Block Chaining
        // (CBC). Use default options for other symmetric key parameters.
        symmetricKey.Mode = CipherMode.CBC;
        // Generate encryptor from the existing key bytes and initialization
        // vector. Key size will be defined based on the number of the key
        // bytes.
        ICryptoTransform encryptor = default(ICryptoTransform);
        encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);

        // Define memory stream which will be used to hold encrypted data.
        MemoryStream memoryStream = default(MemoryStream);
        memoryStream = new MemoryStream();

        // Define cryptographic stream (always use Write mode for encryption).
        CryptoStream cryptoStream = default(CryptoStream);
        cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
        // Start encrypting.
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);

        // Finish encrypting.
        cryptoStream.FlushFinalBlock();
        // Convert our encrypted data from a memory stream into a byte array.
        byte[] cipherTextBytes = null;
        cipherTextBytes = memoryStream.ToArray();

        // Close both streams.
        memoryStream.Close();
        cryptoStream.Close();

        // Convert encrypted data into a base64-encoded string.
        string cipherText = null;
        cipherText = Convert.ToBase64String(cipherTextBytes);

        functionReturnValue = cipherText;
        return functionReturnValue;
    
    public string Decrypt(string cipherText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize)
    
        string functionReturnValue = null;

        // Convert strings defining encryption key characteristics into byte
        // arrays. Let us assume that strings only contain ASCII codes.
        // If strings include Unicode characters, use Unicode, UTF7, or UTF8
        // encoding.


            byte[] initVectorBytes = null;
            initVectorBytes = Encoding.ASCII.GetBytes(initVector);

            byte[] saltValueBytes = null;
            saltValueBytes = Encoding.ASCII.GetBytes(saltValue);

            // Convert our ciphertext into a byte array.
            byte[] cipherTextBytes = null;
            cipherTextBytes = Convert.FromBase64String(cipherText);

            // First, we must create a password, from which the key will be
            // derived. This password will be generated from the specified
            // passphrase and salt value. The password will be created using
            // the specified hash algorithm. Password creation can be done in
            // several iterations.
            PasswordDeriveBytes password = default(PasswordDeriveBytes);
            password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations);

            // Use the password to generate pseudo-random bytes for the encryption
            // key. Specify the size of the key in bytes (instead of bits).
            byte[] keyBytes = null;
            keyBytes = password.GetBytes(keySize / 8);

            // Create uninitialized Rijndael encryption object.
            RijndaelManaged symmetricKey = default(RijndaelManaged);
            symmetricKey = new RijndaelManaged();

            // It is reasonable to set encryption mode to Cipher Block Chaining
            // (CBC). Use default options for other symmetric key parameters.
            symmetricKey.Mode = CipherMode.CBC;

            // Generate decryptor from the existing key bytes and initialization
            // vector. Key size will be defined based on the number of the key
            // bytes.
            ICryptoTransform decryptor = default(ICryptoTransform);
            decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);

            // Define memory stream which will be used to hold encrypted data.
            MemoryStream memoryStream = default(MemoryStream);
            memoryStream = new MemoryStream(cipherTextBytes);

            // Define memory stream which will be used to hold encrypted data.
            CryptoStream cryptoStream = default(CryptoStream);
            cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);

            // Since at this point we don't know what the size of decrypted data
            // will be, allocate the buffer long enough to hold ciphertext;
            // plaintext is never longer than ciphertext.
            byte[] plainTextBytes = null;
            plainTextBytes = new byte[cipherTextBytes.Length + 1];

            // Start decrypting.
            int decryptedByteCount = 0;
            decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

            // Close both streams.
            memoryStream.Close();
            cryptoStream.Close();

            // Convert decrypted data into a string.
            // Let us assume that the original plaintext string was UTF8-encoded.
            string plainText = null;
            plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);

            // Return decrypted string.
            functionReturnValue = plainText;


        return functionReturnValue;
    

【讨论】:

嗨。干净清爽。我尝试使用 cryptObj.Encrypt(用户名,“TAMIZHAN TAMIZHAN DHAAN”,“VAZHGATAMIZH”,“SHA1”,3,“@1B2c3D4e5F6g7H8”,256)。它奏效了。 为什么类不是静态的?

以上是关于在 C# 中使用 AES 加密的主要内容,如果未能解决你的问题,请参考以下文章

Java aes加密C#解密的取巧方法

AES加密

快速的 AES 加密

用c#做aes加密 为啥在线解密解不了

algorithm - C# 中的 RijndaelManaged 类是不是等同于 AES 加密?

使用 RijndaelManaged 在 C# 中加密/解密流