簡體   English   中英

為什么我會收到“指定的算法無效”異常

[英]Why am I getting "Invalid algorithm specified" exception

這是我的代碼。

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);

在最后一行我得到了例外:

System.Security.Cryptography.CryptographicException “指定的算法無效。”

我究竟做錯了什么?

更新:

id = 2.16.840.1.101.3.4.2.1

對於 dot net framework 4.7.0 或更高版本不采用 sha1,因此在應用程序啟動中配置以下內容。 它對我來說很好。

 AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
 AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);

.NET 代碼或您提供的 CSP 代碼沒有問題。

您的問題是 CSP 不支持 SHA 256。您可以在此處獲取更多信息

請注意,我使用 SHA512,但 SHA256 將適用於以下示例:

“指定的算法無效”我花了很長時間才弄清楚,我幾乎嘗試了所有方法。

第 1 步- 證書必須是 SHA512 並使用支持 SHA512 的 CSP(加密服務提供商)。 以下是 CSP 及其功能的列表。 如果您尋找 SHA512,您會找到“Microsoft Enhanced RSA and AES Cryptographic Provider”。 默認情況下生成證書不使用它(至少在 Windows 中),因此您必須在創建證書時指定它。

如果您使用 openssl 創建證書,則可以使用下面的選項 -CSP 來設置正確的 CSP 以使其正常工作。 如果您有現有的 pfx,則可以使用 openssl 將其轉換為 PEM 文件,然后再轉換回 pfx 以添加選項。

創建私鑰和證書 - 此步驟將詢問您問題、州、地區等。

openssl req -x509 -nodes -sha512 -newkey rsa:2048 -keyout 512key.pem -out 512cert.pem -days 3650

使用 Microsoft 增強型 RSA 和 AES 加密提供程序創建 PFX 文件以導入您的證書存儲:

openssl pkcs12 –export –in 512cert.pem –inkey 512key.pem –CSP “Microsoft Enhanced RSA and AES Cryptographic Provider” –out 512pfx.pfx

第 2 步:支持 Gonzalo Gallotti 將鏈接發布到幫助我的代碼段。 我評論了我的代碼以顯示每個步驟在做什么。 注意:如果沒有正確生成的證書,如步驟 1 所述,此代碼將無法工作

public void GetCertificate() {
    
    // Get the Machine Cert Store
    var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

    string alg = CryptoConfig.MapNameToOID("SHA512");

    // Open the cert store
    store.Open(OpenFlags.ReadWrite);

    // Loop through each certificate within the store
    foreach (X509Certificate2 myCert in store.Certificates)
    {
        // Get the certificate we are looking for
        if (myCert.IssuerName.Name.Contains("CN=YourSite"))
        {
            // Check if the certificate has a private key
            if (myCert.HasPrivateKey)
            {
                // Get your custom signature as a string
                string mySignature = GetSignatureString();

                // Convert signature to byte array
                byte[] originalData = Encoding.UTF8.GetBytes(mySignature);

                // Create RSA provider from private key
                RSACryptoServiceProvider rsaProvider = (RSACryptoServiceProvider)myCert.PrivateKey;

                // Sign the signature with SHA512
                byte[] signedSignature = signedSignature = rsaProvider.SignData(originalData, alg);

                if (rsaProvider.VerifyData(originalData, alg, signedSignature))
                {
                    // Signature is verified Do Stuff
                }
                else
                {
                    throw new Exception("The data does not match the signature.");
                }
            }
        }
    }
}

您可能在將應用程序從 .NET Framework 4.7 及更早版本遷移到 4.7.1 或更高版本時來到這里。
如果您收到異常System.Security.Cryptography.CryptographicException: Invalid algorithm specified. ,原因是針對 .NET Framework 4.7.1 及更高版本的應用程序的默認 SignedXML 和 SignedXMS 算法更改為 SHA256( 來自 Microsoft .NET 遷移指南

在該指南中,您還將找到解決方案:

對於面向 .NET Framework 4.7.1 及更高版本的應用程序,如果不希望使用 SHA256,您可以通過將以下配置開關添加到應用程序配置文件的運行時部分來將默認設置恢復為 SHA1:

 <AppContextSwitchOverrides value="Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms=true; Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms=true" />

但這可能並不總是有效,特別是對於 Web 應用程序,正如您可以在這篇文中看到的那樣,幸運的是,它也提供了答案。 只需在Application_Start中添加幾行

protected void Application_Start(object sender, EventArgs e)
{
   [...]
   AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
   AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);
}

可以使用 certutil 工具(在 Windows 上)檢查您的證書正在使用哪個 CSP

certutil yourCertificate.p12

在此處輸入圖像描述

例子:

  • Microsoft Enhanced Cryptographic Provider v1.0 => 在 C# 4.7 及更高版本中拋出錯誤
  • Microsoft 增強型 RSA 和 AES 加密提供程序=> 有效

有類似的問題,但剛剛解決了。 如果您不使用 X509 而只是使用普通的 RSACryptoServiceProvider 來獲取密鑰,則僅支持 SHA1。

您可以通過 appSettings 在 Web 配置中設置 AppContext 開關:

<appSettings>
  <add key="AppContext.SetSwitch:Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms" value="true" />
  <add key="AppContext.SetSwitch:Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms" value="true" />
</appSettings>

我通過升級我的依賴項解決了這個問題。

我沒有依賴我以前使用多年的 GAC 版本,而是切換到最新的 NuGet 包 (v16.8.0):

  • Microsoft.Build.Tasks.Core
  • Microsoft.Build.Utilities.Core
  • Microsoft.Build.Framework

這為我們解決了這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM