Використання AES-шифрування в C #


118

Я не можу знайти гарний чистий приклад використання 128-бітового шифрування AES.

Хтось має якийсь зразок коду?


Досить гарна стаття з цього приводу тут: codeproject.com/Articles/769741/…
scotru

Відповіді:


143

Якщо ви просто хочете використовувати вбудований постачальник криптовалюти 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;

        }
    }
}

25
Ваш код не зберігає IV разом із шифровим текстом, що робить його важким правильним користуванням та легким для зловживання. IV не є вторинним ключем, його слід генерувати випадковим чином для кожного шифрування та зберігати поряд із шифротекстом.
CodesInChaos

1
Для майбутніх читачів: я оновив зразок коду тут оновленим кодом з зразка на MSDN
Dan Esparza

4
Також: Не забувайте, що ви, швидше за все, небезпечно погані в криптографії. happybearsoftware.com/…
Dan Esparza

5
Звичайно, там ви йдете. msdn.microsoft.com/de-de/library/… Погляньте на зауваження. Ви можете використовувати rijndael, але це може призвести до проблем із сумісністю під час зміни налаштувань. Для цього я б використав Aes-Class, якщо ви хочете зашифрувати AES (FIPS-197)
Daniel Abou Chleih

2
@EricJ. using ()Блок автоматично має об'єкт myRijndael (і будь-який інший об'єкт RijndaelManaged в цьому прикладі). Можливо, ваш коментар стосувався попередньої версії відповіді, або посилання показувало погані приклади, але це сьогодні не так.
Даніель

54

Нещодавно мені довелося знову зіткнутися з цим у власному проекті - і хотів поділитися дещо простішим кодом, який я використовував, оскільки це запитання та ряд відповідей постійно виникали в моїх пошуках.

Я не збираюся вникати в питання безпеки щодо того, як часто оновлювати такі речі, як ваш вектор « Сіль» та « Ініціалізація» - це тема форуму безпеки. Це просто блок коду для реалізації AesManagedв C #.

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. Список доступних SymmetricAlgorithmспадкоємців для .NET 4.5 можна знайти за адресою:

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);

Я сподіваюся, що це корисно для когось там.


10
Я отримую помилку: "Помилка Назва" GetBytes "не існує в поточному контексті." Як я можу це вирішити? EDIT: виправлено його за допомогою ASCIIEncoding.ASCII.GetBytes та UTF8Encoding.UTF8.GetBytes.
cvocvo

Боюся, ні, @DeveloperX. Код покладається на бібліотеки криптографії .NET, тому я гадаю, що або вам доведеться знайти еквівалентний набір бібліотек на Java, або прокатати власну. :(
Трой Алфорд

Привіт Трой, у мене є ті ж запитання, що й cvocvo сказав. Повідомлення є The name 'GetBytes' does not exist in the current context. Чи можу я запитати вас, яку версію .Net Framework ви використовуєте?
Джонні

1
Ваш код невірний, у Розшифруванні змініть рядок "valuebytes" на такий: `byte [] valueBytes = Convert.FromBase64String (value);`. Причиною цього є те, що в Encrypt ви перетворили ToBase64, тому тепер вам потрібно ConvertFromBase64String в дешифрувати, інакше ви отримаєте помилкову помилку довжини.
Євфіфро

3
Оновлення IV - це кожне повідомлення, а не дебати, просто зрозуміло, як ви використовуєте AES-CBC, ця відповідь явно неправильна.
jbtule

13

Подивіться зразок тут ..

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

Приклад на MSDN не працює нормально (виникає помилка) , тому що немає ніякого початкового значення з вихідного вектора (IV) і ключа . Я додаю 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 ();
Яванська дівчина

1
Ви можете змінити режим AES, змінивши цей код рядка rijAlg.Mode = CipherMode.CBC; Наприклад, rijAlg.Mode = CipherMode.CFB; або rijAlg.Mode = CipherMode.ECB; Подивіться на [посилання] inconteam.com/software-development/41-encryption/…, якщо ви хочете перевірити AES, функціонує він нормально чи ні.
Яванська дівчина

9

Використовуючи AES чи впроваджувати AES? Для використання AES існує клас System.Security.Cryptography.RijndaelManaged.


так, я розумію, але я не можу зрозуміти, як реалізувати 128-бітний CFB з 32 символами в якості ключа (nibble). Ви знаєте, як редагувати вищевказаний код. Я jsut почав. Здається, потрібна додаткова допомога
ckv

8

Для більш повного прикладу, який виконує виведення ключів на додаток до шифрування AES, див. Відповідь та посилання, розміщені в розділі Отримання шифрування AES для роботи через Javascript та C # .

Редагувати
бічну примітку: Криптографія Javascript вважається шкідливою. Варто прочитаного.


8
//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;  
     }

4
Остерігайтеся: я бачу відсутні зведені заяви ().
SandRock

Привіт! Якась конкретна причина використовувати накладки PKCS7 над іншими варіантами? З того, що я прочитав, він поступається прокладці OAEP, яка чомусь недоступна для AES. Чи PKCS7 безпечніший при AES, ніж в RSA?
Даніель

5

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 тощо.
Джон Генкель

4

Спробуйте цей код, можливо, корисний.
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.

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;
        }

    }
}

2

Ви можете використовувати пароль з текстового поля, як ключ ... За допомогою цього коду ви можете зашифрувати / розшифрувати текст, зображення, документ із слова, 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;
    }

Можливий IndexOutOfRangeException в ConvertPasswordToByte, якщо пароль містить більше 32 символів.
Філіп Корнеліссен

1
Ваш IV має бути випадковим і зберігатися разом із текстом цифри (але не зашифрованим).
andleer

2

ось чіткий і чистий код для розуміння алгоритму AES 256, реалізованого у функції C # call Encrypt як 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). Це спрацювало.
Крішна Сантош Сампат

чому клас не є статичним?
Бен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.