1

暗号化/復号化を試みるまで、シリアル化されたクラスの書き込みを正常に読み取ることができます...ここに私のコードのスニペットがあります:

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%123456789ABCDEF0123456789abcdef").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%123456789ABCDEF0123456789abcdef").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);
4

1 に答える 1

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

}
于 2012-07-17T13:42:56.083 に答える