2012-07-16 37 views
1

我能读,直到我尝试加密/解密...这里的写我的序列化类罚款是我的代码片段:读/写加密的XML

public class ShelfCache 
{ 
    public Shelf Data; 
    public ShelfCache() 
    { 
     Data = new Shelf(); 
    } 

    public void Write(string Filename) 
    { 
     XmlSerializer xsl = new XmlSerializer(typeof(Shelf)); 
     TextWriter xslWriter = new StreamWriter(Filename); 
     xsl.Serialize(xslWriter, Data); 
     xslWriter.Flush(); 
     xslWriter.Close(); 
    } 

    public void Read(string Filename) 
    { 
     Data = new Shelf(); 
     XmlSerializer xsl = new XmlSerializer(typeof(Shelf)); 
     TextReader xslReader = new StreamReader(Filename); 
     Data = (Shelf)xsl.Deserialize(xslReader); 
     xslReader.Close(); 
    } 

    public void WriteEncrypted(string Filename, string EncryptionKey = "") 
    { 
     string _Key = EncryptionKey + Environment.ExpandEnvironmentVariables("%USERNAME%%COMPUTERNAME%123456789ABCDEFabcdef").Substring(0, 32); 
     string _IV = Environment.ExpandEnvironmentVariables("%COMPUTERNAME%123456789abcdef").Substring(0, 16); 
     byte[] Key = Encoding.UTF8.GetBytes(_Key); 
     byte[] IV = Encoding.UTF8.GetBytes(_IV); 

     FileStream CacheStream = new FileStream(Filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); 
     RijndaelManaged CryptoProvider = new RijndaelManaged(); 
     ICryptoTransform CacheTransform = CryptoProvider.CreateEncryptor(Key, IV); 
     CryptoStream EncryptionStream = new CryptoStream(CacheStream, CacheTransform, CryptoStreamMode.Write); 
     XmlSerializer xsl = new XmlSerializer(typeof(Shelf)); 
     xsl.Serialize(EncryptionStream, Data); 
     EncryptionStream.Flush(); 
     CacheStream.Close(); 
    } 

    public void ReadEncrypted(string Filename, string EncryptionKey = "") 
    { 
     string _Key = EncryptionKey + Environment.ExpandEnvironmentVariables("%USERNAME%%COMPUTERNAME%123456789ABCDEFabcdef").Substring(0, 32); 
     string _IV = Environment.ExpandEnvironmentVariables("%COMPUTERNAME%123456789abcdef").Substring(0, 16); 
     byte[] Key = Encoding.UTF8.GetBytes(_Key); 
     byte[] IV = Encoding.UTF8.GetBytes(_IV); 

     FileStream CacheStream = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 
     RijndaelManaged CryptoProvider = new RijndaelManaged(); 
     ICryptoTransform CacheTransform = CryptoProvider.CreateEncryptor(Key, IV); 
     CryptoStream DecryptionStream = new CryptoStream(CacheStream, CacheTransform, CryptoStreamMode.Read); 
     XmlSerializer xsl = new XmlSerializer(typeof(Shelf)); 
     Data = (Shelf)xsl.Deserialize(DecryptionStream); 
     CacheStream.Close(); 
    } 

} 

我得到的异常“有一个XML文档(11)中的错误“。有一个内部例外“根层数据无效,第1行,第1位”。上线:

 Data = (Shelf)xsl.Deserialize(DecryptionStream); 
+1

你不能写一个加密的XML文档。您可以:写入XML文件,然后自行加密文件。或者,加密你的数据(二进制格式,不是XML)然后解密:解密数据并构建你的XML文件。 – Botonomous 2012-07-16 17:00:02

+0

@Anon so [this](http://www.w3.org/TR/xmlenc-core/)不存在? – 2012-07-16 19:20:24

+0

好的 - 我应该指定我不希望文件的任何部分是人类可读的......我尝试从XmlSerializer更改为BinaryFormatter ...使用BinaryFormatter并且没有加密,我无法成功读取文件。 ..我认为这可能与文件的大小有关,因为当我只注释掉大部分数据(嵌套对象列表占用大约25KB的磁盘空间)时它是成功的...... – 2012-07-16 21:41:02

回答

1

这是我落得这样做(我不喜欢的解决方案,但它的工作原理)...

public class ShelfCache 
{ 
    public Shelf Data; 

    public ShelfCache() 
    { 
     Data = new Shelf(); 
    } 

    public void Write(string Filename) 
    {   
     XmlSerializer CacheSerializer = new XmlSerializer(typeof(Shelf)); 
     TextWriter CacheWriter = new StreamWriter(Filename); 
     CacheSerializer.Serialize(CacheWriter, Data); 
     CacheWriter.Flush(); 
     CacheWriter.Close(); 
    } 

    public void Read(string Filename) 
    { 
     Data = new Shelf(); 
     XmlSerializer CacheSerializer = new XmlSerializer(typeof(Shelf)); 
     TextReader CacheReader = new StreamReader(Filename); 
     Data = (Shelf)CacheSerializer.Deserialize(CacheReader); 
     CacheReader.Close(); 
    } 

    public void WriteEncrypted(string Filename, string EncryptionKey = "") 
    { 
     string TempFile = System.IO.Path.GetTempFileName(); 
     Write(TempFile); 
     EncryptFile(TempFile, Filename, EncryptionKey); 
     File.Delete(TempFile); 
    } 

    public void ReadEncrypted(string Filename, string EncryptionKey = "") 
    { 
     string TempFile = System.IO.Path.GetTempFileName(); 
     DecryptFile(Filename, TempFile, EncryptionKey); 
     Read(TempFile); 
     File.Delete(TempFile); 
    } 

    private RijndaelManaged GetEncryptor(string Key = "", string Salt = "") 
    { 
     Key += Environment.ExpandEnvironmentVariables("%USERNAME%"); 
     Salt += Environment.ExpandEnvironmentVariables("%COMPUTERNAME%"); 
     Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(Key, Encoding.Unicode.GetBytes(Salt)); 
     RijndaelManaged rijndaelCSP = new RijndaelManaged(); 
     rijndaelCSP.Key = derivedKey.GetBytes(rijndaelCSP.KeySize/8); 
     rijndaelCSP.IV = derivedKey.GetBytes(rijndaelCSP.BlockSize/8); 
     return rijndaelCSP; 
    } 

    private void EncryptFile(string Source, string Target, string EncryptionKey) 
    { 
     RijndaelManaged EncryptionProvider = GetEncryptor(EncryptionKey); 
     ICryptoTransform Encryptor = EncryptionProvider.CreateEncryptor(); 

     FileStream SourceStream = new FileStream(Source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 
     byte[] SourceBytes = new byte[(int)SourceStream.Length]; 
     SourceStream.Read(SourceBytes, 0, (int)SourceStream.Length); 
     FileStream TargetStream = new FileStream(Target, FileMode.Create, FileAccess.Write); 
     CryptoStream EncryptionStream = new CryptoStream(TargetStream, Encryptor, CryptoStreamMode.Write); 
     EncryptionStream.Write(SourceBytes, 0, (int)SourceStream.Length); 
     EncryptionStream.FlushFinalBlock(); 

     EncryptionProvider.Clear(); 
     EncryptionStream.Close(); 
     SourceStream.Close(); 
     TargetStream.Close(); 
    } 

    private void DecryptFile(string Source, string Target, string EncryptionKey) 
    { 
     RijndaelManaged EncryptionProvider = GetEncryptor(EncryptionKey); 
     ICryptoTransform Decryptor = EncryptionProvider.CreateDecryptor(); 

     FileStream SourceStream = new FileStream(Source, FileMode.Open, FileAccess.Read); 
     CryptoStream DecryptionStream = new CryptoStream(SourceStream, Decryptor, CryptoStreamMode.Read); 
     byte[] SourceBytes = new byte[(int)SourceStream.Length]; 
     int DecryptionLength = DecryptionStream.Read(SourceBytes, 0, (int)SourceStream.Length); 
     FileStream TargetStream = new FileStream(Target, FileMode.Create, FileAccess.Write); 
     TargetStream.Write(SourceBytes, 0, DecryptionLength); 
     TargetStream.Flush(); 

     EncryptionProvider.Clear(); 
     DecryptionStream.Close(); 
     SourceStream.Close(); 
     TargetStream.Close(); 
    } 

} 
+0

很高兴它工作正常斯蒂芬,谢谢你回报。过一段时间后你可以接受你自己的答案。请注意,我不记得暗示你在使用PBKDF2,你可能是第一个自己申请而没有提示的人:) – 2012-07-17 21:17:20