我使用SymmetricAlgorithm (特别是AesCryptoServiceProvider)来加密和解密很多消息。
(注:伪代码)
parallel-foreach (var message, key, iv in triplets)
{
using (var algorithm = CreateAes())
using (var transform = algorithm.CreateEncryptor(key, iv))
{
// do stuff using transform
}
}在创建algorithm之后,我不会改变它,与它的唯一交互是使用它作为ICryptoTransform工厂的CreateEncryptor。
当我将algorithm的创建移出循环时:
using (var algorithm = CreateAes())
{
parallel-foreach (var message, key, iv in triplets)
{
using (var transform = algorithm.CreateEncryptor(key, iv))
{
// do stuff using transform
}
}
}我得到了5倍的性能提升,它确实像预期的那样工作,所以它值得一试。
在这种情况下,我找不到SymmetricAlgorithm是否是线程安全的。我自己不会改变它,但它可能会在幕后发生?
发布于 2018-03-23 21:40:02
AesCryptoServiceProvider的建设和处置都不是轻量级的。这就是当你不在循环中实例化它时,你会看到性能提升的原因:
[System.Security.SecurityCritical]
public AesCryptoServiceProvider () {
Contract.Ensures(m_cspHandle != null && !m_cspHandle.IsInvalid && !m_cspHandle.IsClosed);
// On Windows XP the AES CSP has the prototype name, but on newer operating systems it has the
// standard name
string providerName = CapiNative.ProviderNames.MicrosoftEnhancedRsaAes;
if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1) {
providerName = CapiNative.ProviderNames.MicrosoftEnhancedRsaAesPrototype;
}
m_cspHandle = CapiNative.AcquireCsp(null,
providerName,
CapiNative.ProviderType.RsaAes,
CapiNative.CryptAcquireContextFlags.VerifyContext,
true);
// CAPI will not allow feedback sizes greater than 64 bits
FeedbackSizeValue = 8;
// Get the different AES key sizes supported by this platform, raising an error if there are no
// supported key sizes.
int defaultKeySize = 0;
KeySizes[] keySizes = FindSupportedKeySizes(m_cspHandle, out defaultKeySize);
if (keySizes.Length != 0) {
Debug.Assert(defaultKeySize > 0, "defaultKeySize > 0");
KeySizeValue = defaultKeySize;
}
else {
throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported));
}
}
/// <summary>
/// Release any CAPI handles we're holding onto
/// </summary>
[System.Security.SecuritySafeCritical]
protected override void Dispose(bool disposing) {
Contract.Ensures(!disposing || m_key == null || m_key.IsClosed);
Contract.Ensures(!disposing || m_cspHandle == null || m_cspHandle.IsClosed);
try {
if (disposing) {
if (m_key != null) {
m_key.Dispose();
}
if (m_cspHandle != null) {
m_cspHandle.Dispose();
}
}
}
finally {
base.Dispose(disposing);
}
}至于线程安全,从文档中可以看到:
此类型的任何公共静态(在Visual Basic中为Shared )成员都是线程安全的。不能保证任何实例成员都是线程安全的。
如果你深入研究源代码,你会发现其中并没有内置的线程安全性。
资料来源:
发布于 2018-03-23 22:08:19
快速伪代码来实现您的算法,同时考虑到Aes实例成员的线程非安全性:
using (var algorithm = CreateAes())
{
parallel-foreach (var message, key, iv in triplets)
{
ICryptoTransform transform;
lock (algorithm)
{
transform = algorithm.CreateEncryptor(key, iv);
}
using (transform)
{
// do stuff using transform
}
}
}https://stackoverflow.com/questions/49450712
复制相似问题