C#在写入磁盘之前加密序列化文件
假设我的程序有一个名为“customer”的类,客户类是可序列化的,所以我可以读取并写入磁盘。 客户类包含我想要加密的敏感信息,我知道可以保证文件安全的唯一方法是:
1 – 将文件序列化到磁盘
2 – 重新打开并加载文件
3 – 加密文件
4 – 将文件重写到磁盘
这样可行,但存在文件可能在其未加密状态下被截获的风险,而且这实际上是非常低效的。
相反,我想:
1 – 在内存中创建文件
2加密内存中的文件
3 – 将加密文件写入磁盘
这可能吗? 如果是这样的话? 提前致谢。
除了注释中表达的关注之外,如果您要问的是如何处理内存中的字节并且只将它们写入文件一次,那么首先将对象序列化为内存流。 加密这些字节并将它们写入文件。
using (var fileStream = File.OpenWrite(theFileName)) using (var memoryStream = new MemoryStream()) { // Serialize to memory instead of to file var formatter = new BinaryFormatter(); formatter.Serialize(memoryStream, customer); // This resets the memory stream position for the following read operation memoryStream.Seek(0, SeekOrigin.Begin); // Get the bytes var bytes = new byte[memoryStream.Length]; memoryStream.Read(bytes, 0, (int)memoryStream.Length); // Encrypt your bytes with your chosen encryption method, and write the result instead of the source bytes var encryptedBytes = yourCrypto.Encrypt(bytes); fileStream.Write(encryptedBytes, 0, encryptedBytes.Length); }
在将类序列化为文件的同时,可以使用CryptoStream进行加密:
byte[] key = { 1, 2, 3, 4, 5, 6, 7, 8 }; // Where to store these keys is the tricky part, // you may need to obfuscate them or get the user to input a password each time byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 }; string path = @"C:\path\to.file"; DESCryptoServiceProvider des = new DESCryptoServiceProvider(); // Encryption using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write)) using (var cryptoStream = new CryptoStream(fs, des.CreateEncryptor(key, iv), CryptoStreamMode.Write)) { BinaryFormatter formatter = new BinaryFormatter(); // This is where you serialize the class formatter.Serialize(cryptoStream, customClass); } // Decryption using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) using (var cryptoStream = new CryptoStream(fs, des.CreateDecryptor(key, iv), CryptoStreamMode.Read)) { BinaryFormatter formatter = new BinaryFormatter(); // This is where you deserialize the class CustomClass deserialized = (CustomClass)formatter.Deserialize(cryptoStream); }
很可能,
让我们说你的课看起来像
public class Customer { public string Name{get;set;} public int salary {get;set;} }
您可以加密对象属性中保存的数据,以便customer.Name =’ABC’可以成为customer.Name =’WQW’之类的东西
比序列化它。
在反序列化时,当您必须显示数据时,必须先将数据解密,然后再向用户显示数据
希望这个帮助
我会创建一个提供属性的序列化类。 读取它(给出一个文件名)返回反序列化的对象,写入它(也给出一个文件名)序列化对象。 我添加了一个带有String密码的第二个属性。 使用它时,您可以加密序列化的对象字符串和nwrite到磁盘或从中读取1.加密,然后反序列化。
要加密,我建议使用密码而不是直接使用密码。 不幸的是我在vb.net中只有一个代码示例:
Function Encrypt(ByVal data As String, ByVal password As String) As String Dim pdb As New Rfc2898DeriveBytes(password, Salt) Dim alg As Rijndael = Rijndael.Create() alg.Key = pdb.GetBytes(32) alg.IV = pdb.GetBytes(16) Dim ms As New IO.MemoryStream Dim cs As New CryptoStream(ms, alg.CreateEncryptor, CryptoStreamMode.Write) cs.Write(System.Text.Encoding.Default.GetBytes(data), 0, data.Length) cs.Close() ms.Close() Return Convert.ToBase64String(ms.ToArray) End Function Private Salt As Byte() = {100, 86, 34, 53, 11, 224, 145, 123, _ 237, 213, 12, 124, 45, 65, 71, 127, _ 135, 165, 234, 164, 127, 234, 231, 211, _ 10, 9, 114, 234, 44, 63, 75, 12} Function Decrypt(ByVal data As String, ByVal password As String) As String Dim pdb As New Rfc2898DeriveBytes(password, Salt) Dim alg As Rijndael = Rijndael.Create() alg.Key = pdb.GetBytes(32) alg.IV = pdb.GetBytes(16) Dim ms As New IO.MemoryStream Dim cs As New CryptoStream(ms, alg.CreateDecryptor, CryptoStreamMode.Write) cs.Write(Convert.FromBase64String(data), 0, Convert.FromBase64String(data).Length) cs.Close() ms.Close() Return System.Text.Encoding.Default.GetString(ms.ToArray) End Function
和
Function EncryptWithHash(ByVal data As String, ByVal passToHash As String) As String Dim _hash As String = getMd5Hash(passToHash) Dim _result As String = Encrypt(data, _hash) Return _result End Function Function DecryptWithHash(ByVal data As String, ByVal passToHash As String) As String Dim _hash As String = getMd5Hash(passToHash) Dim _result As String = Encrypt(data, _hash) Return _result End Function Function getMd5Hash(ByVal input As String) As String ' Create a new instance of the MD5CryptoServiceProvider object. Dim md5Hasher As New MD5CryptoServiceProvider() ' Convert the input string to a byte array and compute the hash. Dim data As Byte() = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input)) ' Create a new Stringbuilder to collect the bytes ' and create a string. Dim sBuilder As New StringBuilder() ' Loop through each byte of the hashed data ' and format each one as a hexadecimal string. Dim i As Integer For i = 0 To data.Length - 1 sBuilder.Append(data(i).ToString("x2")) Next i ' Return the hexadecimal string. Return sBuilder.ToString() End Function
我的代码中的属性有Get:
Dim _dataC As String = ReadFile(filename) Dim _dataR As String = Crypt.Decrypt(_dataC, password) Dim _result = tmpS.ReadString(_dataR)
并设置:
Dim _tmpS As New Custom.Serialization(Of Object) Dim _tmpRaw As String = _tmpS.WriteString(value) Dim _tmpCrypt As String = Crypt.Encrypt(_tmpRaw, password) WriteFile(tmpPath, _tmpCrypt)
你必须定义自己的序列化,并读/写文件:
My.Computer.FileSystem.WriteAllText(filename, data, False) _result = My.Computer.FileSystem.ReadAllText(FileName)