2016-11-03 8 views
0

更新日:問題はでした。私はでした!私は間違いを犯しました。そうでなければ、コードとその下の数字はPSです。でも、私は何か新しいことを学んだ@ルークパークの素晴らしい答えのおかげです。非ベース64文字の文字列を暗号化する方法

私は、暗号化/復号化アルゴリズムに精通していないです、そのため私は、ネットを検索し、このクラスを見つけました:

Encrypting & Decrypting a String in C#

コードは次のとおりです。 (Iは大文字でDecrypt方法でのtry/catchを追加

:パスワードは、それが return "";

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

namespace EncryptStringSample 
{ 
    public static class StringCipher 
    { 
     // This constant is used to determine the keysize of the encryption algorithm in bits. 
     // We divide this by 8 within the code below to get the equivalent number of bytes. 
     private const int Keysize = 256; 

     // This constant determines the number of iterations for the password bytes generation function. 
     private const int DerivationIterations = 1000; 

     public static string Encrypt(string plainText, string passPhrase) 
     { 
      // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text 
      // so that the same Salt and IV values can be used when decrypting. 
      var saltStringBytes = Generate256BitsOfRandomEntropy(); 
      var ivStringBytes = Generate256BitsOfRandomEntropy(); 
      var plainTextBytes = Encoding.UTF8.GetBytes(plainText); 
      using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations)) 
      { 
       var keyBytes = password.GetBytes(Keysize/8); 
       using (var symmetricKey = new RijndaelManaged()) 
       { 
        symmetricKey.BlockSize = 256; 
        symmetricKey.Mode = CipherMode.CBC; 
        symmetricKey.Padding = PaddingMode.PKCS7; 
        using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes)) 
        { 
         using (var memoryStream = new MemoryStream()) 
         { 
          using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) 
          { 
           cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); 
           cryptoStream.FlushFinalBlock(); 
           // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes. 
           var cipherTextBytes = saltStringBytes; 
           cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray(); 
           cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray(); 
           memoryStream.Close(); 
           cryptoStream.Close(); 
           return Convert.ToBase64String(cipherTextBytes); 
          } 
         } 
        } 
       } 
      } 
     } 

    public static string Decrypt(string cipherText, string passPhrase) 
    { 
     // Get the complete stream of bytes that represent: 
     // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText] 
     var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText); 
     // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes. 
     var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize/8).ToArray(); 
     // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes. 
     var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize/8).Take(Keysize/8).ToArray(); 
     // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string. 
     var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize/8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize/8) * 2)).ToArray(); 
     try 
     { 
      using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations)) 
      { 
       var keyBytes = password.GetBytes(Keysize/8); 
       using (var symmetricKey = new RijndaelManaged()) 
       { 
        symmetricKey.BlockSize = 256; 
        symmetricKey.Mode = CipherMode.CBC; 
        symmetricKey.Padding = PaddingMode.PKCS7; 
        using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes)) 
        { 
         using (var memoryStream = new MemoryStream(cipherTextBytes)) 
         { 
          using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) 
          { 
           var plainTextBytes = new byte[cipherTextBytes.Length]; 
           var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); 
           memoryStream.Close(); 
           cryptoStream.Close(); 
           return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); 
          } 
         } 
        } 
       } 
      } 
     } 
     catch (Exception) 
     { 
      return ""; 
     } 
    } 

     private static byte[] Generate256BitsOfRandomEntropy() 
     { 
      var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits. 
      using (var rngCsp = new RNGCryptoServiceProvider()) 
      { 
       // Fill the array with cryptographically secure random bytes. 
       rngCsp.GetBytes(randomBytes); 
      } 
      return randomBytes; 
     } 
    } 
} 

私はこのような私のアプリケーションでそのクラスを使用します間違っていました

string plaintext = "InsertedPasswordByUserToEncrypt"; 
string password = plaintext; // use its own password as encryption key 
string encryptedstring = StringCipher.Encrypt(plaintext, password); 

私は同じデータで最後の行を繰り返すと、私に異なる暗号化結果を与える原因になります。

しかし、文字列はbase64で文字以外の文字を持っている場合今、私はそれがこの例外を上昇するだろうアウトが見つかりました: 「それは非ベース64文字が含まれているように、入力が有効なベース-64文字列ではありません」私はネットを検索し、この問題に対する多くの答えを見つけました。これらのように:すべてのこれらの質問に

The input is not a valid Base-64 string as it contains a non-base 64 character

How can I solver an "base64 invalid characters" error?

が、答えは同じだった:

あなたの文字列から非base64で文字を削除します!であること、または「CanYouGu3 $$ Meは?」か....:

しかし、私や私のアプリケーションのユーザーは、このような文字列を挿入したい場合はどのような「@のS番号のD $を?」暗号化された?

私の質問:

A1。ユーザーが暗号化するために挿入できる文字を置き換えたり削除したりすることなく、上のクラスの問題を解決する方法はありますか?

A2。修正がない場合、他の最良の方法は何ですか?どのような方法で私はそれを使用することができますそれは任意の文字列で任意の文字列を暗号化/復号化することができます。

PS:このコードはまた良いものです(それはまた、任意の例外を防ぐために、このメソッドEncoding.UTF8.GetBytesを使用する原因)既存の非BASE64文字で問題ありません。お時間

ため https://codereview.stackexchange.com/questions/14892/simplified-secure-encryption-of-a-string

感謝

答えて

3

入力文字列をバイト配列に変換し、それをbase64に変換します。入力された文字列は有効なbase64であり、まだ暗号化できます。

byte[] data = Encoding.UTF8.GetBytes(inputString); 
string b64 = Convert.ToBase64String(data); 

なぜbase64が必要なのかを理解するために時間を費やしたいことがあります。暗号化アルゴリズムは文字列ではなく、バイト配列、生データで動作します。

+0

お返事ありがとうございます。私はまた別の間違いをした!私は修正しました!さて、上のコード(私のスタートアップポストのコード)は何の問題もなく働いています。 (実際のところ、元のコードは正しいですが、私の修正で私は間違いを犯しました!今修正しました) – MRK

+0

@MRK助けて嬉しいです。 –

関連する問題