15

我的高级目标是创建一个封装我的 .NET 应用程序加密的静态实用程序类。在里面,我想尽量减少不必要的对象创建。

我的问题是:在 .NET Framework 中实现对称加密的类的线程安全性是什么? 具体来说System.Security.Cryptography.RijndaelManaged以及ICryptoTransform它生成的类型。

例如,在我的类构造函数中,我可以简单地按照以下几行做一些事情吗?

static MyUtility()
{
    using (RijndaelManaged rm = new RijndaelManaged())
    {
        MyUtility.EncryptorTransform = rm.CreateEncryptor(MyUtility.MyKey, MyUtility.MyIV);
        MyUtility.DecryptorTransform = rm.CreateDecryptor(MyUtility.MyKey, MyUtility.MyIV);
    }
}

回避在这个类中存在 Key 和 IV 是否安全的问题,这个示例块提出了许多其他问题:

  1. 我可以不断重复使用 EncryptorTransform 和 DecryptorTransform 吗?和属性暗示“是” *.CanReuseTransform*.CanTransformMultipleBlocks但有什么我应该注意的警告吗?

  2. 由于RijndaelManaged实现IDisposable了我的倾向是将它放在一个using块中,特别是因为它可能与外部操作系统级库相关联。既然我把ICryptoTransform物体放在身边,有什么注意事项吗?

  3. 可能是最重要的问题,在高度多线程的环境中,我是否会遇到ICryptoTransform在线程之间共享对象的问题?

  4. 如果#3 的答案是它不是线程安全的,那么我在使用ICryptoTransform对象时是否会因锁定而导致性能严重下降?(我想取决于负载。)

  5. RijndaelManaged每次都简单地实例化 new 会更好吗?还是存储一个RijndaelManagednew RijndaelManaged().CreateEncryptor(...)每次生成?

我希望有人知道这些在幕后是如何工作的,或者对类似实现的问题有经验。我发现很多此类性能和线程相关问题通常在负载相当大时才会显现出来。

谢谢!

4

3 回答 3

18

1) 是的。

2)你丢弃它,你不能使用它。在那之前,您可以共享/使用它(但见下文)

3-4) 来自MSDN

“这种类型的任何公共静态(在 Visual Basic 中为共享)成员都是线程安全的。不保证任何实例成员都是线程安全的。”

如果您想保留它并在线程之间共享它,则需要实现锁定并将其视为锁定资源。否则,我建议只根据需要制作单独的版本,并在完成后处理它们。

5) 我建议根据需要创建这些,然后在以后发现性能问题时尝试对其进行优化。不要担心创建新版本对性能的影响,直到您在分析后发现这是一个问题。

于 2009-06-12T00:55:59.740 回答
4

可以简单地使用基于并发堆栈的缓存来解决并发问题:

static ConcurrentStack<ICryptoTransform> decryptors = new ConcurrentStack<ICryptoTransform>();

void Encrypt()
{
   // Pop decryptor from cache...
   ICryptoTransform decryptor;
   if (!decryptors.TryPop(out decryptor))
   {
       // ... or create a new one since cache is depleted
       AesManaged aes = new AesManaged();
       aes.Key = key;
       aes.IV = iv;
       decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
    }

    try
    {
       //// use decryptor
    }
    finally
    {
       decryptors.Push(decryptor);
    }
 }
于 2013-06-21T00:44:35.453 回答
0
  1. 绝对不是,我遇到了麻烦。我已经使用它两年了,突然我的一些最重要的代码在解密时开始抛出错误。微软补丁的结果?迈克菲?点网框架更新?(框架 4.7.2)

当我最终弄清楚时,我将 CreateEncryptor 和 CreateDecryptor 移到了实际调用中的 using 中以进行加密和解密。问题已解决。

于 2020-10-02T11:39:32.107 回答