2012-02-20 7 views
1

私は何が間違っているのか分かりませんが、暗号化はうまくいくようですが、復号化に至ったときに逆シリアル化しようとすると悪いデータが表示されます。私は暗号化をやっているときに新しいので、それが本当にシンプルなものならば、すみません。構造体の暗号化、不正なデータエラー、何が原因ですか?

public byte[] Serialize(object obj, string key) 
    { 
     byte[] returnBytes; 
     using (MemoryStream memory = new MemoryStream()) 
     { 
      UTF8Encoding UTF8 = new UTF8Encoding(); 
      TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider(); 
      MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); 
      byte[] pass = provider.ComputeHash(UTF8.GetBytes(key)); 
      crypt.Key = pass; 
      crypt.Mode = CipherMode.ECB; 
      crypt.Padding = PaddingMode.PKCS7; 
      using (CryptoStream stream = new CryptoStream(memory, crypt.CreateEncryptor(), CryptoStreamMode.Write)) 
      { 
       BinaryFormatter formatter = new BinaryFormatter(); 
       formatter.Serialize(stream, obj); 
       stream.Close(); 
       memory.Close(); 
      } 

      returnBytes = memory.ToArray(); 
     } 

     return returnBytes; 
    } 
    public object Deserialize(byte[] inBytes, string key) 
    { 
     object returnObj; 
     using (MemoryStream memory = new MemoryStream()) 
     { 
      UTF8Encoding UTF8 = new UTF8Encoding(); 
      TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider(); 
      MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); 
      byte[] pass = provider.ComputeHash(UTF8.GetBytes(key)); 
      crypt.Key = pass; 
      crypt.Mode = CipherMode.ECB; 
      crypt.Padding = PaddingMode.PKCS7; 
      using (CryptoStream stream = new CryptoStream(memory, crypt.CreateDecryptor(), CryptoStreamMode.Read)) 
      { 
       BinaryFormatter formatter = new BinaryFormatter(); 
       returnObj = formatter.Deserialize(stream); 
       stream.Close(); 
       memory.Close(); 
      } 
      return returnObj; 
     } 

    } 

私はしばらく前にやったこのコードは、それが毎回ランダムな値としてオフ始めているので、文字列

 public string encrypt(string message, string password) 
     { 
      byte[] result; 
      UTF8Encoding UTF8 = new UTF8Encoding(); 
      MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); 
      byte[] key = provider.ComputeHash(UTF8.GetBytes(password)); 
      TripleDESCryptoServiceProvider algorithm = new TripleDESCryptoServiceProvider(); 
      algorithm.Key = key; 
      algorithm.Mode = CipherMode.ECB; 
      algorithm.Padding = PaddingMode.PKCS7; 
      byte[] data = UTF8.GetBytes(message); 
      try 
      { 
       ICryptoTransform encryptor = algorithm.CreateEncryptor(); 
       result = encryptor.TransformFinalBlock(data, 0, data.Length); 
      } 
      finally 
      { 
       algorithm.Clear(); 
       provider.Clear(); 
      } 
      return Convert.ToBase64String(result); 
     } 
     public string decrypt(string message, string passsword) 
     { 
      byte[] result; 
      UTF8Encoding UTF8 = new UTF8Encoding(); 
      MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); 
      byte[] key = provider.ComputeHash(UTF8.GetBytes(passsword)); 
      TripleDESCryptoServiceProvider algorithm = new TripleDESCryptoServiceProvider(); 
      algorithm.Key = key; 
      algorithm.Mode = CipherMode.ECB; 
      algorithm.Padding = PaddingMode.PKCS7; 
      byte[] data = Convert.FromBase64String(message); 
      try 
      { 
       ICryptoTransform decryptor = algorithm.CreateDecryptor(); 
       result = decryptor.TransformFinalBlock(data, 0, data.Length); 
      } 
      finally 
      { 
       algorithm.Clear(); 
       provider.Clear(); 
      } 
      return UTF8.GetString(result); 
     } 
+1

)'メソッドは ''新しいのMemoryStream(inBytes)すべきではありませんか? –

+0

構造体は変更可能ですか? – Lloyd

+0

memorystreamにinBytesを追加しようとしました – Shredder2500

答えて

2

あなたはcryptIVプロパティを設定していない上で動作します。ハッシュのための塩のように、暗号化のときと同じように解読するときに同じ値に設定する必要があります。編集:ECBの仕組みを考えると、IVが無視されるように見えます。これは、以前のコードが保存されずに機能する理由です。

EDIT:非ECBのIV部分は確かに必要ですが、それだけでは十分ではありません。しかし、残りの問題はわかりません:

  • ECB暗号モードは推奨されません - それを使用する理由は何ですか?
  • パディングが原因で問題が発生する可能性があります。 BinaryFormatterが自動的にそれを処理するかどうかはわかりませんが、調べる価値はあります。

EDIT:Doh - 私は大きな問題を解決しました。 Elianのコメントに従って実際にinBytesを使用する必要があります。現在、あなたは完全に暗号テキストを無視しています - それはには、のチャンスがあります!

はここで一緒にぶら下がって全体のことを示す完全なプログラムです: `逆シリアル化(中

using System; 
using System.IO; 
using System.Text; 
using System.Security.Cryptography; 
using System.Runtime.Serialization.Formatters.Binary; 

class Test 
{ 
    static void Main() 
    { 
     byte[] data = Serialize("Some arbitrary test data", "pass"); 
     object x = Deserialize(data, "pass"); 
     Console.WriteLine(x); 
    } 

    private static SymmetricAlgorithm CreateCryptoServiceProvider(string key) 
    { 
     byte[] passwordHash; 
     using (MD5 md5 = MD5.Create()) 
     { 
      // It's not clear why you're taking the hash of the password... 
      passwordHash = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); 
     } 
     var crypt = new TripleDESCryptoServiceProvider(); 
     crypt.Key = passwordHash; 
     crypt.Mode = CipherMode.CBC; // This is the default anyway - can remove 
     crypt.Padding = PaddingMode.PKCS7; // Ditto 
     // Fix this to use a randomly generated one and store it for real code. 
     crypt.IV = new byte[crypt.BlockSize/8]; 
     return crypt; 
    } 

    public static byte[] Serialize(object obj, string key) 
    { 
     var provider = CreateCryptoServiceProvider(key); 

     using (MemoryStream memory = new MemoryStream()) 
     { 
      using (CryptoStream stream = new CryptoStream(
       memory, provider.CreateEncryptor(), CryptoStreamMode.Write)) 
      { 
       BinaryFormatter formatter = new BinaryFormatter(); 
       formatter.Serialize(stream, obj); 
      } 
      return memory.ToArray(); 
     } 
    } 

    public static object Deserialize(byte[] inBytes, string key) 
    { 
     var provider = CreateCryptoServiceProvider(key); 

     using (MemoryStream memory = new MemoryStream(inBytes)) 
     { 
      using (CryptoStream stream = new CryptoStream(
       memory, provider.CreateDecryptor(), CryptoStreamMode.Read)) 
      { 
       BinaryFormatter formatter = new BinaryFormatter(); 
       return formatter.Deserialize(stream); 
      } 
     } 
    } 

} 
+0

私はちょうどIVを設定しましたが、それでも同じエラーが発生しませんでした – Shredder2500

+0

@ user1216963:どうしましたか? –

+0

私はオブジェクトをシリアライズしたときにランダムに生成されたIVを保存しました。デシリアライズ時に使用しました – Shredder2500

関連する問題