Cryptography 多线程/TPL应用程序中的静态加密/解密问题

Cryptography 多线程/TPL应用程序中的静态加密/解密问题,cryptography,task-parallel-library,static-methods,rijndaelmanaged,Cryptography,Task Parallel Library,Static Methods,Rijndaelmanaged,我的一个库中有一个静态加密/解密类,其中包含静态方法。代码有点大,所以我将其发布在这里: 我对这段代码没有任何问题,直到它开始在执行Parallel.ForEach()调用的某些代码的执行堆栈中使用。我尝试在一些MemoryStream和CryptoStream变量上添加了一些lock,但似乎没有什么帮助。我这样做是因为我相当确定这个问题是由从多个线程访问这个静态类和方法引起的 我一直得到的例外是:“填充无效,无法删除。” 当执行到达decryptedTextStream.FlushFinalB

我的一个库中有一个静态加密/解密类,其中包含静态方法。代码有点大,所以我将其发布在这里:

我对这段代码没有任何问题,直到它开始在执行
Parallel.ForEach()
调用的某些代码的执行堆栈中使用。我尝试在一些MemoryStream和CryptoStream变量上添加了一些
lock
,但似乎没有什么帮助。我这样做是因为我相当确定这个问题是由从多个线程访问这个静态类和方法引起的

我一直得到的例外是:“填充无效,无法删除。”

当执行到达decryptedTextStream.FlushFinalBlock()时,会发生此异常在名为Decrypt的代码中的最后一个方法中(第250行)


我的问题是-我不知道代码有什么问题,我想知道唯一的问题是类和方法是静态的吗?我几个月来一直在使用这段代码,没有一个问题,直到最近在其他一些TPL代码中开始使用它时才遇到问题。我应该把这个类重构成基于实例的类,还是这样就不能解决我遇到的异常呢?

你的代码根本不是线程安全的。。。 会发生什么?目前,您有一个只创建一次的iCryptoTransform(静态构造函数),因此每个加密/解密调用都将使用该对象

这有两个问题:

  • 如果两个或多个线程尝试并行加密/解密会怎么样? 您的系统具有在所有调用中共享的内部状态,这是错误的,因为在具有IV的操作模式下,每个加密块都取决于之前的块。。。这对安全有好处。。。但是,如果之前加密的块不属于当前的块流,那就非常糟糕了,因为另一个块在同一时间通过同一个实例

  • 你不在乎你的iCryptoTransform是否可重复使用。。。在您的情况下是这样的,但通常需要检查CanReuseTransform成员或为每个操作创建一个新成员

  • 建议:


    让您的ICryptoTransform在Encrypt()/Decrypt()方法中运行。。。不要使用静态变量…

    我想我现在明白你的意思了。我可能应该使用两个ICryptotTransforms(encryptorTransform和decryptorTransform)以及utfEncoder,在静态方法中创建它们的新实例,而不是让它们成为静态类中的静态字段。是吗?我刚刚做了我上面描述的,现在一切都很好-谢谢你的指点。对于将来可能阅读这个问题的其他人来说,这里有一个关于使用静态与实例方法以及线程安全性的很好的解释:“我尝试在一些变量上添加一些锁的用法”,这是一个非常危险的方法。这样,很可能会使代码出现细微错误。与猜测不同,您应该充分了解如何使代码真正实现线程安全。您是对的-我读了一些书,准确地了解了如何使代码实现线程安全,并且我能够删除代码中锁的所有用法。:)