C# 是否可以通过DataContractSerializer反序列化加密文件?

C# 是否可以通过DataContractSerializer反序列化加密文件?,c#,serialization,encryption,datacontractserializer,C#,Serialization,Encryption,Datacontractserializer,我正在通过DataContractSerializer序列化一个对象,没有任何问题 但如果我现在尝试将该对象序列化为加密文件,则在反序列化时会出现异常 这是我的密码: public static bool SerializeDataContract<t>(Stream fileStream, t o, bool bCrypt = false) { DataContractSerializer serializer = new DataContr

我正在通过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;
    }
publicstaticboolserializedDataContract(streamfilestream,to,boolbcrypt=false)
{
DataContractSerializer serializer=新的DataContractSerializer(typeof(t));
if(bCrypt)
{
TripleDESCryptoServiceProvider crypt=新的TripleDESCryptoServiceProvider();
crypt.IV=crypt_INIT_向量;
Key=crypt\u Key;
crypt.Padding=PaddingMode.zero;
使用(CryptoStream CryptoStream=new CryptoStream(fileStream,crypt.CreateEncryptor(),CryptoStreamMode.Write))
{
serializer.WriteObject(cryptoStream,o);
cryptoStream.Close();
}
}
其他的
serializer.WriteObject(fileStream,o);
返回true;
}
公共静态bool反序列化datacontract(流fileStream,out t o,bool bCrypt=false)
{
o=默认值(t);
尝试
{
DataContractSerializer serializer=新的DataContractSerializer(typeof(t));
if(bCrypt)
{
TripleDESCryptoServiceProvider crypt=新的TripleDESCryptoServiceProvider();
crypt.IV=crypt_INIT_向量;
Key=crypt\u Key;
crypt.Padding=PaddingMode.zero;
使用(CryptoStream CryptoStream=new CryptoStream(fileStream,crypt.CreateDecryptor(),CryptoStreamMode.Read))
{
//TraceXML(加密流);
o=(t)serializer.ReadObject(cryptoStream);
cryptoStream.Close();
}
}
其他的
{
o=(t)serializer.ReadObject(fileStream);
}
}
捕获(例外情况除外)
{
返回false;
}
返回true;
}
如果我用bCrypt=false调用这两个函数,那么一切都会按预期进行。但是如果调用bCrypt=true的函数,则在反序列化时会出现异常

异常为(从德语转换为英语):SerializationException:根级别的数据无效

如果我跟踪解密后读取的数据,数据对我来说似乎没有问题,也就是说,它看起来就像没有加密的序列化

你知道我的代码中的错误在哪里吗


或者不能使用DataContractSerializer加密?

如果在描述流之后将其保存到文件中,我认为您可以很容易地理解问题所在

只需在加密之前将其与序列化文件进行比较

如果它们相等,那么在解密程序完成其工作之前,反序列化就太早了

我认为您不需要调用
cryptoStream.Close()改为调用Flush()


我将使用memoryStream作为缓冲区,而不是直接将CryptoStream传递给DataContractSerializer和viceversa。

问题是加密数据用零填充,因此原始数据的长度不明显

这里有一种方法可以删除它们,以便反序列化工作:

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);
        }
    }
}

这正是我错过的,谢谢。您确定在末尾删除零没有问题吗?是否保证流末尾的所有零都用于填充?应该是因为您最初加密的xml永远不会有最终的零。您是对的,我没有意识到您正在删除解密流上的零。