2

問題なく DataContractSerializer を介してオブジェクトをシリアル化しています。

しかし、このオブジェクトを暗号化されたファイルにシリアライズしようとすると、デシリアライズ時に例外が発生します。

これが私のコードです:

        public static bool SerializeDataContract<t>(Stream fileStream, t o, bool bCrypt = false)
    {
        DataContractSerializer serializer = new DataContractSerializer(typeof(t));
        if(bCrypt)
        {
            TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider();
            crypt.IV = CRYPT_INIT_VECTOR;
            crypt.Key = CRYPT_KEY;
            crypt.Padding = PaddingMode.Zeros;

            using(CryptoStream cryptoStream = new CryptoStream(fileStream, crypt.CreateEncryptor(), CryptoStreamMode.Write))
            {
                serializer.WriteObject(cryptoStream, o);
                cryptoStream.Close();
            }
        }
        else
            serializer.WriteObject(fileStream, o);
        return true;
    }
    public static bool DeserializeDataContract<t>(Stream fileStream, out t o, bool bCrypt = false)
    {
        o = default(t);

        try
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(t));
            if(bCrypt)
            {
                TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider();
                crypt.IV = CRYPT_INIT_VECTOR;
                crypt.Key = CRYPT_KEY;
                crypt.Padding = PaddingMode.Zeros;

                using(CryptoStream cryptoStream = new CryptoStream(fileStream, crypt.CreateDecryptor(), CryptoStreamMode.Read))
                {
                    //TraceXML(cryptoStream);

                    o = (t)serializer.ReadObject(cryptoStream);
                    cryptoStream.Close();
                }
            }
            else
            {
                o = (t)serializer.ReadObject(fileStream);
            }
        }
        catch(Exception ex)
        {
            return false;
        }

        return true;
    }

bCrypt=false で 2 つの関数を呼び出すと、すべてが期待どおりに機能します。しかし、bCrypt=true で関数を呼び出すと、デシリアライズ時に例外が発生します。

例外は次のとおりです (ドイツ語から英語への翻訳): SerializationException: ルート レベルのデータが無効です。

復号化後に読み取られたデータをトレースすると、データは問題ないように見えます。つまり、暗号化なしのシリアル化のように見えます。

私のコードのどこにバグがあるか知っていますか?

それとも、DataContractSerializer で暗号化を使用できないのでしょうか?

4

2 に答える 2

1

問題は、暗号化されたデータにゼロが埋め込まれているため、元のデータの長さがわからなくなることです。

デシリアライズが機能するようにそれらを削除する 1 つの方法を次に示します。

using(var cryptoStream = 
      new CryptoStream(fileStream, crypt.CreateDecryptor(), CryptoStreamMode.Read))
{               
    using(var reader = new StreamReader(cryptoStream))
    {
        var s = reader.ReadToEnd().TrimEnd(new char[]{'\0'});

        using(var stream = new MemoryStream(Encoding.ASCII.GetBytes(s)))
        {
            o = (t)serializer.ReadObject(stream);
        }
    }
}
于 2013-03-04T15:21:37.327 に答える
0

解読されたストリームをファイルに保存すると、どこに問題があるのか​​簡単に理解できると思います

暗号化する前に、シリアル化されたファイルと比較するだけです。

それらが等しい場合、デシリアライズするのが早すぎて、デクリプターがその仕事をしません。

cryptoStream.Close();代わりに Call Flush()を呼び出す必要はないと思います

CryptoStream を DataContractSerializer に直接渡す代わりに、memoryStream をバッファとして使用します。

于 2013-03-04T15:20:52.180 に答える