我可以将SymmetricAlgorithm视为ICryptoTransform的工厂吗?

时间:2018-03-23 13:24:51

标签: c# .net encryption encryption-symmetric

我使用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,只有与CreateEncryptor进行互动才能将ICryptoTransform用作using (var algorithm = CreateAes()) { parallel-foreach (var message, key, iv in triplets) { using (var transform = algorithm.CreateEncryptor(key, iv)) { // do stuff using transform } } } 工厂。

当我将算法的创建移出循环时:

SymmetricAlgorithm

我获得了5倍的性能提升,并且按预期工作,所以值得尝试。

如果let button = document.createElement("button"); button.innerHTML = "Start!!!"; let body = document.body.appendChild(button); button.addEventListener("click", startPage);//Pass a function. Not make a function call function startPage() { button.style.display = "block" loadWords(); }; function loadWords() { console.log('loadWords called'); };在这种情况下是线程安全的,我无法找到。我自己并没有改变它,但它可能会在幕后发生吗?

2 个答案:

答案 0 :(得分:1)

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)成员都是   线程安全。任何实例成员都不能保证是线程   安全

如果深入了解源代码,可以看到内置的线程安全性没有。

来源:

Reference Source for .NET 4.7.1

AesCryptoServiceProvider Class Documentation

答案 1 :(得分:0)

在尊重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
        }
    }
}