我有一个高级目标,即创建一个static 实用程序类来封装我的 .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 是否安全的问题,这个示例 block 提出了许多其他问题:
我能否不断重复使用 EncryptorTransform 和 DecryptorTransform?
*.CanReuseTransform
和*.CanTransformMultipleBlocks
属性暗示"is",但有什么我应该注意的注意事项吗?由于
RijndaelManaged
实现了IDisposable
,我倾向于将它放在using
block 中,尤其是因为它可能与外部操作系统相关联 -水平库。由于我保留了ICryptoTransform
对象,这有什么注意事项吗?可能是最重要的问题,在高度多线程的环境中,我是否会遇到在线程之间共享
ICryptoTransform
对象的问题?如果问题 3 的答案是它不是线程安全的,那么在使用
ICryptoTransform
对象时,我是否会因锁定而严重降低性能? (我想取决于负载。)每次都简单地实例化新的
RijndaelManaged
会不会更高效?或者每次存储一个RijndaelManaged
并生成new RijndaelManaged().CreateEncryptor(...)
?
我希望有人知道这些在引擎盖下是如何工作的,或者对类似实现的问题有经验。我发现很多这类性能和线程相关的问题通常在负载相当大时才会显现出来。
谢谢!
最佳答案
1) 是的。
2) 一个你处理掉它,你不能使用它。在那之前,您可以共享/使用它(但请参阅下文)
3-4) 来自MSDN :
“此类型的任何公共(public)静态(在 Visual Basic 中为共享)成员都是线程安全的。不保证任何实例成员都是线程安全的。”
如果你想保留它并在线程之间共享它,你需要实现锁定并将其视为锁定资源。否则,我建议只根据需要制作单独的版本,并在完成后处理它们。
5) 我建议根据需要创建这些,然后在您发现性能问题时尝试对其进行优化。不要担心创建新版本的性能影响,直到您在分析后发现这是一个问题。
关于c# - .NET 加密类的线程安全性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/984525/