Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将对象序列化为字节[],然后加密该字节[]_C#_.net_Encryption - Fatal编程技术网

C# 将对象序列化为字节[],然后加密该字节[]

C# 将对象序列化为字节[],然后加密该字节[],c#,.net,encryption,C#,.net,Encryption,我遇到了一个案例,我需要加密一个对象,以便通过.NET远程处理连接将其发送以进行传递。我已经在代码中实现了字符串加密,因此我使用了类似的设计来加密对象: public static byte[] Encrypt(object obj) { byte[] bytes = ToByteArray(toEncrypt); // code below using (SymmetricAlgorithm algo = SymmetricAlgorithm.Creat

我遇到了一个案例,我需要加密一个对象,以便通过.NET远程处理连接将其发送以进行传递。我已经在代码中实现了字符串加密,因此我使用了类似的设计来加密对象:

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

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

我能想到的唯一一件事是,通常在加密数据后,应该在纯文本数组上写入空值。这使得纯文本无法在内存中恢复,如果它以页面文件或交换的形式写入磁盘,恶意程序/用户将无法恢复。如果数据的敏感性不是一个问题,这可能不是必要的,但这是一个好习惯

编辑:


尽管如此,如果你不需要的话,千万不要自己滚(你很少这样做)。除非你真的知道自己在做什么,否则很有可能你会把它搞砸,让它很容易受到攻击。如果您不了解或不喜欢内置的API,那么位于的代理在创建库供您使用以及使用多种不同语言方面做了出色的工作。

这里的目标是什么?如果您只对通过网络传输的数据的安全性感兴趣,那么既然您使用的是支持透明加密的.NET远程处理,为什么不使用它,而不是自己动手实现它呢

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


作为进一步说明,由于您的密钥和IV都是使用Encoding.ASCII.GetBytes(用于7位ASCII输入)从字符串转换而来的,因此您显著减少了有效密钥空间。

不知道为什么要这样做,但没有理由担心。抱歉,StackOverFlow不允许我只说“不”,即使你将明文字节数组归零,那么原始对象呢?即使将其所有字段设置为空,也有可能是GC移动了它,在内存或页面文件中留下了原始数据的残余。@Iridium是的,当然也有可能是原始对象(特别是不可变的,如Java中的字符串)仍在内存中或被GC移动了。这是内置GC的缺点之一。但是,我不会因为可能有另一个副本在某处而忽略将数组置零。没有理由保证有副本,或者复制副本以使其更容易找到。此外,纯文本离密文越远,RE识别它就越困难。REs喜欢相邻的两个指针。我不知道如何设置加密的远程处理会话,时间限制使我使用加密字符串的方法用于其他目的。IV是在这些函数之外生成和附加的,尽管我不记得为什么一开始就这样做。