将对象序列化为byte [],然后加密byte []

时间:2013-04-19 18:45:13

标签: c# .net encryption

我遇到了一个案例,我需要加密一个对象,以便通过.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;
      }

通过这种方式序列化和加密对象,我需要注意什么?

2 个答案:

答案 0 :(得分:3)

这里的目标究竟是什么?如果您只对线上数据的安全性感兴趣,那么既然您使用支持透明加密的.NET远程处理,为什么不使用它,而不是自己实现它的麻烦?

如果您坚持执行自己的加密,那么值得注意的是您似乎使用的是常量IV,这是不正确的。 IV应该是随机字节数组,并且对于每个加密消息是不同的。在传输之前,这通常是加密消息的前置,以便在解密过程中使用。

另外请注意,由于您的密钥和IV都是使用Encoding.ASCII.GetBytes从字符串转换而来的,这对于7位ASCII输入是有意义的,因此您将显着减少有效密钥空间。

答案 1 :(得分:1)

我唯一能想到的是,通常在加密数据之后,你应该在带有NULL的纯文本数组上写。这样,普通文本在内存中无法恢复,如果在页面文件或交换中写入磁盘,则恶意程序/用户无法恢复。如果数据的敏感性不是一个问题,这可能没有必要,但这是一个很好的习惯。

编辑:

尽管如此,永远不会推出自己的,如果你不需要(你很少做)。机会非常好你会搞砸它并使它容易受到攻击,除非你真的知道你正在做什么。如果你不理解或不喜欢内置的API,那么Bouncy Castle的gents在创建库以供你使用时,以及在许多不同的语言中都做了出色的工作。