none
微软MSDN中AES类示例代码求解惑

    问题

  • 各位专家:

        微软在AES类的解释中给出了示例代码(原文地址:https://msdn.microsoft.com/zh-cn/library/bb352381(v=vs.110).aspx),我将代码拷贝运行,得到如下结果:

       

        的确,加密解密成功了。

        但是,并没有提示让我输入自己的加密密码啊?

        我想知道:

        1、我自己的密码(比方说:123456)要怎么样才能输入呢?要如何修改代码?

        2、当我想加密的不是string字符串时(例如想加密一个MP3文件),这段代码改如何更改?

        还请指教。

        下面是MSDN中AES类给出的示例代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Security.Cryptography;
    using System.IO;
    
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
    
                    string original = "Here is some data to encrypt!";
    
                    // Create a new instance of the Aes
                    // class.  This generates a new key and initialization 
                    // vector (IV).
                    using (Aes myAes = Aes.Create())
                    {
    
                        // Encrypt the string to an array of bytes.
                        byte[] encrypted = EncryptStringToBytes_Aes(original,myAes.Key, myAes.IV);
    
                        // Decrypt the bytes to a string.
                        string roundtrip = DecryptStringFromBytes_Aes(encrypted,myAes.Key, myAes.IV);
    
                        //Display the original data and the decrypted data.
                        Console.WriteLine("Original:   {0}", original);
                        Console.WriteLine("Round Trip: {0}", roundtrip);
    
                        Console.ReadLine();//自己加了这一句
                    }
    
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error: {0}", e.Message);
                }
    
            }
    
            static byte[] EncryptStringToBytes_Aes(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 Aes object
                // with the specified key and IV.
                using (Aes aesAlg = Aes.Create())
                {
                    aesAlg.Key = Key;
                    aesAlg.IV = IV;
    
                    // Create a decrytor to perform the stream transform.
                    ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.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_Aes(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 Aes object
                // with the specified key and IV.
                using (Aes aesAlg = Aes.Create())
                {
                    aesAlg.Key = Key;
                    aesAlg.IV = IV;
    
                    // Create a decrytor to perform the stream transform.
                    ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.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;
    
            }
    
        }
    }
    

           

    2016年9月13日 9:35

答案

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

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

           string key=Console.ReadLine();  用户输入密码

           myAes.Key=GetBytes(key);  输化为字节数组

    static byte[] GetBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    • 已标记为答案 wxysy 2016年9月18日 1:17
    • 取消答案标记 wxysy 2016年9月18日 12:35
    • 已标记为答案 wxysy 2016年10月14日 1:11
    2016年9月13日 12:18

全部回复

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

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

           string key=Console.ReadLine();  用户输入密码

           myAes.Key=GetBytes(key);  输化为字节数组

    static byte[] GetBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    • 已标记为答案 wxysy 2016年9月18日 1:17
    • 取消答案标记 wxysy 2016年9月18日 12:35
    • 已标记为答案 wxysy 2016年10月14日 1:11
    2016年9月13日 12:18
  • 你好,

    加解密问件,可以参考下面的方法:

    using System;
    using System.IO;
    using System.Security;
    using System.Security.Cryptography;
    using System.Runtime.InteropServices;
    using System.Text;
    
    namespace CSEncryptDecrypt
    {
       class Class1
       {
          //  Call this function to remove the key from memory after use for security
          [System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint="RtlZeroMemory")]
          public static extern bool ZeroMemory(IntPtr Destination, int Length);
    		
          // Function to Generate a 64 bits Key.
          static string GenerateKey() 
          {
             // Create an instance of Symetric Algorithm. Key and IV is generated automatically.
             DESCryptoServiceProvider desCrypto =(DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
    
             // Use the Automatically generated key for Encryption. 
             return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
          }
    
          static void EncryptFile(string sInputFilename,
             string sOutputFilename, 
             string sKey) 
          {
             FileStream fsInput = new FileStream(sInputFilename, 
                FileMode.Open, 
                FileAccess.Read);
    
             FileStream fsEncrypted = new FileStream(sOutputFilename, 
                FileMode.Create, 
                FileAccess.Write);
             DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
             DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
             DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
             ICryptoTransform desencrypt = DES.CreateEncryptor();
             CryptoStream cryptostream = new CryptoStream(fsEncrypted, 
                desencrypt, 
                CryptoStreamMode.Write); 
    
             byte[] bytearrayinput = new byte[fsInput.Length];
             fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
             cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
             cryptostream.Close();
             fsInput.Close();
             fsEncrypted.Close();
          }
    
          static void DecryptFile(string sInputFilename, 
             string sOutputFilename,
             string sKey)
          {
             DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
             //A 64 bit key and IV is required for this provider.
             //Set secret key For DES algorithm.
             DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
             //Set initialization vector.
             DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
    
             //Create a file stream to read the encrypted file back.
             FileStream fsread = new FileStream(sInputFilename, 
                FileMode.Open, 
                FileAccess.Read);
             //Create a DES decryptor from the DES instance.
             ICryptoTransform desdecrypt = DES.CreateDecryptor();
             //Create crypto stream set to read and do a 
             //DES decryption transform on incoming bytes.
             CryptoStream cryptostreamDecr = new CryptoStream(fsread, 
                desdecrypt,
                CryptoStreamMode.Read);
             //Print the contents of the decrypted file.
             StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
             fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
             fsDecrypted.Flush();
             fsDecrypted.Close();
          } 
    
          static void Main()
          {
             // Must be 64 bits, 8 bytes.
             // Distribute this key to the user who will decrypt this file.
             string sSecretKey;
             
             // Get the Key for the file to Encrypt.
             sSecretKey = GenerateKey();
    
             // For additional security Pin the key.
             GCHandle gch = GCHandle.Alloc( sSecretKey,GCHandleType.Pinned );
             
             // Encrypt the file.        
             EncryptFile(@"C:\MyData.txt", 
                @"C:\Encrypted.txt", 
                sSecretKey);
    
             // Decrypt the file.
             DecryptFile(@"C:\Encrypted.txt", 
                @"C:\Decrypted.txt", 
                sSecretKey);
    
             // Remove the Key from memory. 
             ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
             gch.Free();
          }
       }
    }

    https://support.microsoft.com/zh-cn/kb/307010

    Best regards,

    Cole Wu


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2016年9月14日 7:10
    版主
  • 感谢版主您的耐心回复。

    我刚学不久,目前还只会照葫芦画瓢,您给出的方案我暂时没办法完全看懂(比方说方括号的使用,比方说各种流之间的关系......),我会好好收藏着的,相信未来能看明白,不懂的地方到时还请赐教。

    2016年9月18日 1:32
  • 您的回答真是一针见血。

    我很想试试这段代码能不能移植到WPF程序中去。

    2016年9月18日 1:37
  • 您好:

        我按照您的建议改写了加密程序,但是出现了下列错误提示:

    我改变密码长度,没有效果。

    不知是哪里出了问题?还请指点。

    我的完整代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Security.Cryptography;
    using System.IO;
    
    namespace CSharp_7_AES
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    string original = "Here is some data to encrypt!";//待加密数据
    
                    // Create a new instance(实例) of the Aes class.  
                    // This generates a new key and initialization(初始化) vector(向量) (IV).
                    using (Aes myAes = Aes.Create())
                    {
                        /*----补充内容------------------------------------------------------*/
                        Console.WriteLine("请输入密码");
                        string myKey = Console.ReadLine();//读取用户输入的密码
                        myAes.Key = myGetBytes(myKey); //输入的密码转化为字节数组供算法使用
                        /*------------------------------------------------------------------*/
    
                        // Encrypt the string to an array of bytes.将数据加密为字节
                        byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);
    
                        // Decrypt the bytes to a string.从字节解密还原成数据
                        string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);
    
                        //Display the original data and the decrypted data.
                        Console.WriteLine("Original:   {0}", original);
                        Console.WriteLine("Round Trip: {0}", roundtrip);
    
                        Console.ReadLine();//为了看结果用
                    }
    
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error: {0}", e.Message);
                    Console.ReadLine(); //为了看结果用
                }
    
            }
            /*----补充内容------------------------------------------------------*/
            //输入的密码转化为字节数组的方法
            static byte[] myGetBytes(string str)
            {
                byte[] bytes = new byte[str.Length * sizeof(char)];
                System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
                return bytes;
            }
            /*------------------------------------------------------------------*/
    
            static byte[] EncryptStringToBytes_Aes(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 Aes object
                // with the specified key and IV.
                using (Aes aesAlg = Aes.Create())
                {
                    aesAlg.Key = Key;
                    aesAlg.IV = IV;
    
                    // Create a decrytor to perform the stream transform.
                    ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.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_Aes(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 Aes object
                // with the specified key and IV.
                using (Aes aesAlg = Aes.Create())
                {
                    aesAlg.Key = Key;
                    aesAlg.IV = IV;
    
                    // Create a decrytor to perform the stream transform.
                    ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.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;
    
            }
    
        }
    }


    • 已编辑 wxysy 2016年9月18日 12:42 多写了一句
    2016年9月18日 12:39