2012-02-19 10 views
0

データを暗号化してファイルに保存する必要があるアプリケーションがあります。このデータは、AESなどの業界標準に暗号化する必要があります。 データは、テキストデータまたはバイナリデータのどちらでもかまいません。C#でデータを暗号化する

キーをどこかに保存するのではなく、キーを使用してデータを復号化するための英数字のパスワードを入力する必要があります。

C#.NET 3.5でこれを行う最良の方法は何ですか?理想的には私はそうのように使用できるブラックボックスクラスを探しています:

byte[] writeThisToFile = EncryptionClass.Encrypt(string data, string password); 

byte[] writeThisToFile = EncryptionClass.Encrypt(byte[] data, string password); 

byte[] plainBinaryData = EncryptionClass.DecryptBinary(byte[] encryptedFileContents, string password); 

string plainText = EncryptionClass.DecryptText(byte[] encryptedFileContents, string password); 
+0

既に組み込まれている.net 3.5。そして、この質問はほとんどの複製です:http://stackoverflow.com/questions/3683277/aes-encryption-and-c-sharp –

+0

http://msdn.microsoft.com/en-us/library/system.security .cryptography.aescryptoserviceprovider.aspx – GSerg

+0

これを確認してください:http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx –

答えて

2
using System.IO; 
    using System.Security; 
    using System.Security.Cryptography; 
    using System.Runtime.InteropServices; 

    // <summary> 
    // Encrypts a string   
    // </summary>   
    // <param name="CipherText">Text to be Encrypted</param>   
    // <param name="Password">Password to Encrypt with</param>   
    // <param name="Salt">Salt to Encrypt with</param>   
    // <param name="HashAlgorithm">Can be either SHA1 or MD5</param>   
    // <param name="PasswordIterations">Number of iterations to do</param>   
    // <param name="InitialVector">Needs to be 16 ASCII characters long</param>   
    // <param name="KeySize">Can be 128, 192, or 256</param>   
    // <returns>A decrypted string</returns>  
    public static string AESEncrypt(string PlainText, string Password, string Salt, string HashAlgorithm, int PasswordIterations, string InitialVector, int KeySize) 
    { 
     if (string.IsNullOrEmpty(PlainText)) 
     { 
      return "The Text to be Decryped by AES must not be null..."; 
     } 
     else if (string.IsNullOrEmpty(Password)) 
     { 
      return "The Password for AES Decryption must not be null..."; 
     } 
     byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector); 
     byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt); 
     byte[] PlainTextBytes = Encoding.UTF8.GetBytes(PlainText); 
     PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations); 
     byte[] KeyBytes = DerivedPassword.GetBytes(KeySize/8); 

     RijndaelManaged SymmetricKey = new RijndaelManaged(); 

     SymmetricKey.Mode = CipherMode.CBC; 

     byte[] CipherTextBytes = null; 

     using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes)) 
     { 

      using (MemoryStream MemStream = new MemoryStream()) 
      { 
       using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write)) 
       { 
        CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length); 
        CryptoStream.FlushFinalBlock(); 
        CipherTextBytes = MemStream.ToArray(); 
        MemStream.Close(); 
        CryptoStream.Close(); 
       } 
      } 
     } 
     SymmetricKey.Clear(); 
     return Convert.ToBase64String(CipherTextBytes); 

    } 


    // <summary> 
    // Decrypts a string   
    // </summary>   
    // <param name="CipherText">Text to be decrypted</param>   
    // <param name="Password">Password to decrypt with</param>   
    // <param name="Salt">Salt to decrypt with</param>   
    // <param name="HashAlgorithm">Can be either SHA1 or MD5</param>   
    // <param name="PasswordIterations">Number of iterations to do</param>   
    // <param name="InitialVector">Needs to be 16 ASCII characters long</param>   
    // <param name="KeySize">Can be 128, 192, or 256</param>   
    // <returns>A decrypted string</returns>   
    public static string AESDecrypt(string CipherText, string Password, string Salt, string HashAlgorithm, int PasswordIterations, string InitialVector, int KeySize) 
    { 
     if (string.IsNullOrEmpty(CipherText)) 
     { 
      return "The Text to be Decryped by AES must not be null..."; 
     } 
     else if (string.IsNullOrEmpty(Password)) 
     { 
      return "The Password for AES Decryption must not be null..."; 
     } 
     byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector); 
     byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt); 
     byte[] CipherTextBytes = Convert.FromBase64String(CipherText); 
     PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations); 
     byte[] KeyBytes = DerivedPassword.GetBytes(KeySize/8); 
     RijndaelManaged SymmetricKey = new RijndaelManaged(); 
     SymmetricKey.Mode = CipherMode.CBC; 
     byte[] PlainTextBytes = new byte[CipherTextBytes.Length]; 
     int ByteCount = 0; 
     try 
     { 

      using (ICryptoTransform Decryptor = SymmetricKey.CreateDecryptor(KeyBytes, InitialVectorBytes)) 
      { 
       using (MemoryStream MemStream = new MemoryStream(CipherTextBytes)) 
       { 
        using (CryptoStream CryptoStream = new CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read)) 
        { 
         ByteCount = CryptoStream.Read(PlainTextBytes, 0, PlainTextBytes.Length); 
         MemStream.Close(); 
         CryptoStream.Close(); 
        } 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      return "Please Enter the Correct Password and Salt..." + "The Following Error Occured: " + "/n" + e; 
     } 
     SymmetricKey.Clear(); 
     return Encoding.UTF8.GetString(PlainTextBytes, 0, ByteCount); 

    } 

は、私がこのコードを取得しました場所を正確に覚えていないことが、私のように暗号化された検索結果を返すように変更された以下の記事を読む詳細については

byte[] writeThisToFile = EncryptionClass.Encrypt(byte[] data, string password); 

byte[] plainBinaryData = EncryptionClass.DecryptBinary(byte[] encryptedFileContents, string password); 

を使用しなければなりません文字列。これらのメソッドはFileEncryptorクラスに簡単にラップすることができます。そこにはもっと良い解決策があると確信していますが...

2

あなたは、「パスワードベースのキー派生機能」、またはPBKDF2を必要としています。 AES 128については

、MD5はあなたに右のサイズ出力を与えるので、これは鍵生成機能として動作します(ただし、読み続ける):

key = md5("MyPassw0rd!"); 

しかし、それは非常に弱いです。 PBKDFは以下のような塩の繰り返しを多く追加します:

salt = "SomeValueDifferentForEachKeyGenerated"; 
key = md5(salt+md5(salt+md5(salt+md5(salt+"MyPassw0rd!")))); 

どちらが優れていますか?まだ弱いです。 MD5は最も強力なハッシュアルゴリズムではなく、十分な反復がありません。

PBKDF functions on StackOverflowの数があり、あなたに最も適したものを選んでください。

+0

ありがとうございましたこれは、ユーザーが入力したパスワードの部分に役立ちます。 – ose

関連する問題