2012-07-16 5 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 문서 (1 1)에서 오류가 발생했습니다. " "루트 레벨의 데이터가 유효하지 않습니다. 라인 1, 위치 1"내부 예외가 있습니다. 라인에 :

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

당신은 암호화 된 XML 문서를 작성하지 못할 ... (내가 솔루션을 좋아하지 않아,하지만 작동)하고 결국 것입니다. 다음 중 하나를 수행 할 수 있습니다. XML 파일을 작성한 다음 자체 파일을 암호화합니다. 또는 데이터를 암호화합니다 (XML이 아닌 바이너리 형식으로). 그런 다음 해독합니다. 데이터를 해독하고 XML 파일을 구성합니다. – Botonomous

+0

@Anon 그래서 [this] (http://www.w3.org/TR/xmlenc-core/)가 존재하지 않습니까? –

+0

알았어 - 파일의 일부를 사람이 읽을 수 없도록 지정해야합니다 ... XmlSerializer에서 BinaryFormatter로 변경하려고했습니다 ... BinaryFormatter를 사용하고 암호화하지 않으면 파일을 성공적으로 다시 읽을 수 없습니다. .. 나는 그것이 파일의 크기와 관련이 있을지도 모른다고 생각한다. 왜냐하면 디스크의 약 25KB를 차지하는 중첩 된 객체의 목록 인 데이터의 대부분을 주석 처리 할 때 성공하기 때문이다. –

답변

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를 사용함을 암시하는 것을 기억하지 않는다는 것을 유의하십시오. 힌트없이 직접 적용 할 수 있습니다. :) –