序列化文件写入磁盘前加密

本文关键字:加密 磁盘 文件 序列化 | 更新日期: 2023-09-27 17:54:59

假设我的程序有一个名为" customer "的类;客户类是可序列化的,所以我可以把它读写到磁盘上。customer类保存着我想要加密的敏感信息,我知道保证文件安全的唯一方法是:

1-将文件序列化到磁盘

2-重新打开并加载文件

3-加密文件

4-重写文件到磁盘

这是可行的,但是存在文件可能在未加密状态下被拦截的风险,而且这真的很低效。

相反,我想:

在内存中创建文件

在内存中加密文件

3—将加密文件写入磁盘

这可能吗?如果是怎么回事?

序列化文件写入磁盘前加密

您可以在将类序列化到文件的同时使用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);
}

除了评论中表达的问题之外,如果所有您想问的是如何处理内存中的字节并且只将它们写入文件一次,那么只需首先将您的对象序列化到内存流。加密这些字节并将它们写入文件。

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

这很有可能,

假设你的类看起来像

public class Customer
{
public string Name{get;set;}
public int salary {get;set;}
}

你可以加密保存在对象属性中的数据所以客户。Name = 'ABC'可以成为客户。Name = 'WQW'之类的

,然后序列化。

在反序列化中,当你必须显示数据时,你必须在向用户显示数据之前解密它

希望对您有所帮助

我将创建一个提供属性的序列化类。读取它(给出一个文件名)返回反序列化的对象,写入它(也给出一个文件名)序列化对象。我添加了第二个带有字符串密码的属性。当使用它时,您可以加密序列化的对象字符串和nwrite到磁盘或从它读取时。加密,然后反序列化。

要加密,我建议使用密码的哈希函数,而不是直接使用它。不幸的是,我只有一个代码示例在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)