我遇到了一个案例,我需要加密一个对象,以便通过.NET Remoting连接发送它。我已经在代码中实现了字符串加密,所以我使用了类似的设计来加密对象:
public static byte[] Encrypt(object obj)
{
byte[] bytes = ToByteArray(toEncrypt); // code below
using (SymmetricAlgorithm algo = SymmetricAlgorithm.Create())
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
byte[] key = Encoding.ASCII.GetBytes(KEY);
byte[] iv = Encoding.ASCII.GetBytes(IV);
using (CryptoStream cs = new CryptoStream(ms, algo.CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
cs.Write(bytes, 0, bytes.Length);
cs.Close();
return ms.ToArray();
}
}
}
}
private static byte[] ToByteArray(object obj)
{
byte[] bytes = null;
if (obj != null)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, obj);
bytes = ms.ToArray();
}
}
return bytes;
}
通过这种方式序列化和加密对象,我需要注意什么?
答案 0 :(得分:3)
这里的目标究竟是什么?如果您只对线上数据的安全性感兴趣,那么既然您使用支持透明加密的.NET远程处理,为什么不使用它,而不是自己实现它的麻烦?
如果您坚持执行自己的加密,那么值得注意的是您似乎使用的是常量IV,这是不正确的。 IV应该是随机字节数组,并且对于每个加密消息是不同的。在传输之前,这通常是加密消息的前置,以便在解密过程中使用。
另外请注意,由于您的密钥和IV都是使用Encoding.ASCII.GetBytes从字符串转换而来的,这对于7位ASCII输入是有意义的,因此您将显着减少有效密钥空间。
答案 1 :(得分:1)
我唯一能想到的是,通常在加密数据之后,你应该在带有NULL的纯文本数组上写。这样,普通文本在内存中无法恢复,如果在页面文件或交换中写入磁盘,则恶意程序/用户无法恢复。如果数据的敏感性不是一个问题,这可能没有必要,但这是一个很好的习惯。
编辑:
尽管如此,永远不会推出自己的,如果你不需要(你很少做)。机会非常好你会搞砸它并使它容易受到攻击,除非你真的知道你正在做什么。如果你不理解或不喜欢内置的API,那么Bouncy Castle的gents在创建库以供你使用时,以及在许多不同的语言中都做了出色的工作。