だから私は基本的な暗号クラスを持っています。これは、質問を説明するための簡略化された実装であることに注意してください。
私の考えでは、これらのメソッドには両方とも追加のバイト配列と文字列インスタンスがあります。
xmlString
とbytes
でEncrypt
と
decryptedString
とdecryptedBytes
でDecrypt
では、メモリ使用量を最小限に抑えるために、このクラスのストリームの使用法をどのように作り直すことができますか?
class Crypto
{
Rijndael rijndael;
public Crypto()
{
rijndael = Rijndael.Create();
rijndael.Key = Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); ;
rijndael.IV = Encoding.ASCII.GetBytes("bbbbbbbbbbbbbbbb"); ;
rijndael.Padding = PaddingMode.PKCS7;
}
public byte[] Encrypt(object obj)
{
var settings = new XmlWriterSettings
{
OmitXmlDeclaration = true
};
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
var sb = new StringBuilder();
var xmlSerializer = new XmlSerializer(obj.GetType());
using (var xmlWriter = XmlWriter.Create(sb, settings))
{
xmlSerializer.Serialize(xmlWriter, obj, ns);
xmlWriter.Flush();
}
var xmlString = sb.ToString();
var bytes = Encoding.UTF8.GetBytes(xmlString);
using (var encryptor = rijndael.CreateEncryptor())
using (var stream = new MemoryStream())
using (var crypto = new CryptoStream(stream, encryptor, CryptoStreamMode.Write))
{
crypto.Write(bytes, 0, bytes.Length);
crypto.FlushFinalBlock();
stream.Position = 0;
var encrypted = new byte[stream.Length];
stream.Read(encrypted, 0, encrypted.Length);
return encrypted;
}
}
public T Decrypt<T>(byte[] encryptedValue)
{
byte[] decryptedBytes;
using (var decryptor = rijndael.CreateDecryptor())
using (var stream = new MemoryStream())
using (var crypto = new CryptoStream(stream, decryptor, CryptoStreamMode.Write))
{
crypto.Write(encryptedValue, 0, encryptedValue.Length);
crypto.FlushFinalBlock();
stream.Position = 0;
decryptedBytes = new Byte[stream.Length];
stream.Read(decryptedBytes, 0, decryptedBytes.Length);
}
var ser = new XmlSerializer(typeof(T));
var decryptedString = Encoding.UTF8.GetString(decryptedBytes);
using (var stringReader = new StringReader(decryptedString))
using (var xmlReader = new XmlTextReader(stringReader))
{
return (T)ser.Deserialize(xmlReader);
}
}
}
そしてここにユニットテストがあります
[TestFixture]
public class Tests
{
[Test]
public void Run()
{
var before = new MyClassForSerialize()
{
Property = "Sdf"
};
var dataEncryptor = new Crypto();
var encrypted = dataEncryptor.Encrypt(before);
var after = dataEncryptor.Decrypt<MyClassForSerialize>(encrypted);
Assert.AreEqual(before.Property, after.Property);
}
}
public class MyClassForSerialize
{
public string Property { get; set; }
}
===編集===
Damien_The_Unbelieverからの回答に基づいて、私はこれを試しました。ユニットテストに失敗する
public byte[] Encrypt(object obj)
{
var settings = new XmlWriterSettings
{
OmitXmlDeclaration = true
};
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
var xmlSerializer = new XmlSerializer(obj.GetType());
using (var encryptor = rijndael.CreateEncryptor())
using (var stream = new MemoryStream())
using (var crypto = new CryptoStream(stream, encryptor, CryptoStreamMode.Write))
{
using (var xmlWriter = XmlWriter.Create(crypto, settings))
{
xmlSerializer.Serialize(xmlWriter, obj, ns);
xmlWriter.Flush();
}
crypto.FlushFinalBlock();
stream.Position = 0;
return stream.ToArray();
}
}