2016-11-10 3 views
-1

私は以下のコードを持っていて、それはほぼ2年間働いていました。しかし、今私たちはパディングとランダムな問題を見始めた。私がランダムに言うと、私は同じことがある日は動作するが、先日は動作しないことを意味します。そして、いつかはランダムに働くことにします。既存の暗号化/復号化コードのパディングオプションを変更するにはどうすればよいですか?

上記の回答のようにパディングを追加しないと、以前に暗号化されたすべてのファイルが混乱する可能性があります。私は、暗号化キーを変更したときと同じ方法で、この方法でcatchブロックでGOTO文を使用して別のアプローチを作成することを考えています。 またはには、パディングをNoneに変更する方法がありますか?

/// <summary> 
/// 
/// </summary> 
[Serializable] 
public static class EncryptDecrypt 
{ 
    private static string EncryptionKey_old = "MAKV2SPBNI99212"; 
    private static string EncryptionKey = "Yi9BpGG1cXR01gBwGPZRTOznoJHpkGBOzisBg5jl3iRu48yhcFGdZu76fDpa5FUu"; 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="clearText"></param> 
    /// <returns></returns> 
    public static string Encrypt(string clearText) 
    { 
     byte[] whitebs = Encoding.Unicode.GetBytes(clearText); 

     using (Aes encryptor = Aes.Create()) 
     { 

      Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 

      encryptor.Key = pdb.GetBytes(32); 

      encryptor.IV = pdb.GetBytes(16); 
      encryptor.Mode = CipherMode.ECB; 
      encryptor.Padding = PaddingMode.PKCS7; 

      using (MemoryStream ms = new MemoryStream()) 
      { 

       using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) 
       { 

        cs.Write(whitebs, 0, whitebs.Length); 
        cs.FlushFinalBlock(); 
        cs.Close(); 
       } 
       clearText = Convert.ToBase64String(ms.ToArray()); 
      } 
     } 
     return clearText.EndsWith("==") ? clearText.Remove(clearText.Length - 2) : clearText; 
    } 
    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="cipherText"></param> 
    /// <returns></returns> 
    public static string Decrypt(string cipherText) 
    { 
     int attempts = 0; 
     string exception = string.Empty; 


     StartHere: 
     cipherText = cipherText.Replace(" ", "+"); 

     byte[] cipherBytes; 
     try { cipherBytes = Convert.FromBase64String(cipherText); } 
     catch { cipherBytes = Convert.FromBase64String(cipherText + "=="); } 

     using (Aes encryptor = Aes.Create()) 
     { 

      Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 

      encryptor.Key = pdb.GetBytes(32); 

      encryptor.IV = pdb.GetBytes(16); 
      encryptor.Mode = CipherMode.ECB; 
      encryptor.Padding = PaddingMode.PKCS7; 
      try 
      { 
       using (MemoryStream ms = new MemoryStream()) 
       { 

        using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) 
        { 

         cs.Write(cipherBytes, 0, cipherBytes.Length); 
         cs.FlushFinalBlock(); 
         cs.Close(); 
        } 

        cipherText = Encoding.Unicode.GetString(ms.ToArray()); 

       } 
      } 
      catch 
      { 
       if (attempts == 2) throw; 
       EncryptionKey = EncryptionKey_old; 
       attempts++; 
       goto StartHere; 
      } 
     } 
     return cipherText; 
    } 
    ' 

今、これを変更する私たちは、このコードで暗号化されたファイルの数千人があるので、私はそれをやって行くだろう方法がわからないのも良いアイデアではありません。

+0

にすることであるです公衆インターネットに投稿した本当のハードコード暗号化キー? – Blorgbeard

+0

いいえ、古いものは本物でしたがもう使用されませんでした。 –

+0

代わりに、なぜこれらのパディングの問題が発生しているのか理解しようとします。あなたがそれを理解すれば、他の何かを変えることについて心配する必要はありません。あなたは間違った方法で問題に近づいています。 –

答えて

2

パディングエラーが復号化が成功したかどうかを判断するために使用されているようですが、それは間違っていて動作しません。成功した復号化を判断する別の方法が必要です。この場合、正しいキーが使用されています。

PKCS#7 paddingを参照してください。

誤ったキーで復号化すると、結果は本質的にランダムなデータとなり、最後のバイトが正しいパディングで0x01になる可能性が1/256あり、パディングエラーは報告されません。より少ない程度で、他の有効なパディングがランダムに発生します。

正しい復号化が得られたかどうかを判断するには、別の方法が必要です。通常、暗号化を認証するためにMACが使用されます。しかし、それは知られているデータ内の何かになる可能性があります。これは一般にcribと呼ばれ、成功率はそれの一意性によって決まります。

再:パディング:暗号化すべきデータの長さが常にブロックサイズ(AES用の16バイト)の倍数でない場合、パディングが必要とPKCS#7パディングが正しいパディング

関連する問題