ใช้การเข้ารหัส AES ใน C #


118

ดูเหมือนจะไม่พบตัวอย่างที่ดีในการใช้การเข้ารหัส AES 128 บิต

ใครมีโค้ดตัวอย่างบ้าง


บทความดีดีที่นี่: codeproject.com/Articles/769741/…
scotru

คำตอบ:


143

หากคุณเพียงแค่ต้องการใช้ RijndaelManaged ผู้ให้บริการ crypto ในตัวให้ดูบทความช่วยเหลือต่อไปนี้ (นอกจากนี้ยังมีตัวอย่างโค้ดง่ายๆ):

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 ไม่ใช่คีย์รองควรสร้างแบบสุ่มสำหรับการเข้ารหัสแต่ละครั้งและจัดเก็บไว้ข้าง ciphertext
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 อื่น ๆ ในตัวอย่างนี้) บางทีความคิดเห็นของคุณอาจเป็นคำตอบในเวอร์ชันก่อนหน้าหรือลิงก์แสดงตัวอย่างที่ไม่ดี แต่นั่นไม่ใช่ในปัจจุบัน
Daniel

54

เมื่อเร็ว ๆ นี้ฉันต้องเผชิญหน้ากับสิ่งนี้อีกครั้งในโครงการของตัวเองและต้องการแบ่งปันรหัสที่ค่อนข้างง่ายกว่าที่ฉันเคยใช้เนื่องจากคำถามและชุดคำตอบนี้ยังคงปรากฏในการค้นหาของฉัน

ฉันจะไม่เข้าไปกังวลเรื่องความปลอดภัยเกี่ยวกับความถี่ในการอัปเดตสิ่งต่างๆเช่นSaltและInitialization Vectorของคุณซึ่งเป็นหัวข้อสำหรับฟอรัมความปลอดภัยและมีแหล่งข้อมูลที่ยอดเยี่ยมให้ดู นี่เป็นเพียงบล็อกโค้ดที่จะใช้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' ไม่มีอยู่ในบริบทปัจจุบัน" ฉันจะแก้ปัญหานี้ได้อย่างไร? แก้ไข: แก้ไขโดยใช้ ASCIIEncoding.ASCII.GetBytes และ UTF8Encoding.UTF8.GetBytes
cvocvo

ฉันไม่กลัว @DeveloperX รหัสนี้อาศัยไลบรารีการเข้ารหัส. NET ดังนั้นฉันเดาว่าคุณต้องหาชุดไลบรารีที่เทียบเท่าใน Java หรือม้วนของคุณเอง :(
Troy Alford

สวัสดีทรอยฉันมีคำถามเหมือนกันเช่น cvocvo กล่าว ข้อความคือThe name 'GetBytes' does not exist in the current context. ขอถามหน่อยได้ไหมว่า. Net framework ที่คุณใช้รุ่นอะไร?
Johnny

1
รหัสของคุณผิดใน Decrypt เปลี่ยนบรรทัด "valuebytes" เป็นดังต่อไปนี้: `byte [] valueBytes = Convert.FromBase64String (value);". สาเหตุนี้เป็นเพราะใน Encrypt คุณแปลง ToBase64 ดังนั้นตอนนี้คุณต้อง ConvertFromBase64String ใน Decrypt มิฉะนั้นคุณจะได้รับข้อผิดพลาดเกี่ยวกับความยาวที่ไม่ถูกต้อง
Euthyphro

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 ();
Javanese Girl

1
คุณสามารถเปลี่ยนโหมด AES ได้ด้วยการเปลี่ยนรหัสบรรทัด rijAlg.Mode = CipherMode.CBC; เช่นถึง rijAlg.Mode = CipherMode.CFB; หรือ rijAlg.Mode = CipherMode.ECB; ดูที่ [ลิงค์] inconteam.com/software-development/41-encryption/…หากคุณต้องการทดสอบ AES ว่าทำงานได้ตามปกติหรือไม่
Javanese Girl

9

ใช้ AES หรือใช้ AES? ในการใช้ AES มีคลาส System.Security.Cryptography.RijndaelManaged


ใช่ฉันเข้าใจ แต่ดูเหมือนจะคิดไม่ออกว่าจะใช้ 128 Bit CFB ที่มีอักขระ 32 ตัวเป็นคีย์ได้อย่างไร (แทะ) คุณรู้วิธีแก้ไขโค้ดด้านบนหรือไม่ ฉันเริ่มต้นได้แล้ว ดูเหมือนจะต้องการความช่วยเหลือเพิ่มเติม
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
ระวัง: ฉันเห็นข้อความ Dispose () หายไป
SandRock

สวัสดี! มีเหตุผลพิเศษในการใช้ PKCS7 padding มากกว่าตัวเลือกอื่น ๆ หรือไม่? จากสิ่งที่ฉันอ่านพบว่ามันด้อยกว่า OAEP padding ซึ่งเป็นเหตุผลบางประการที่ใช้ไม่ได้กับ AES PKCS7 ปลอดภัยกว่าใน AES มากกว่า RSA หรือไม่?
Daniel

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 เป็นต้น
John Henckel

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 เพื่อสร้าง Initial Vector (IV) และ KEY ของ 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 ตัว
Filip Cornelissen

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) มันได้ผล
Krishna Santosh Sampath

ทำไมคลาสไม่นิ่ง
เบ็น
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.