为什么我收到“指定的无效算法”异常

时间:2011-09-15 15:04:34

标签: c# cryptography

这是我的代码。

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

8 个答案:

答案 0 :(得分:11)

.NET代码或您提供的CSP代码没有问题。

您的问题是CSP不支持SHA 256.您可以获得更多信息here

答案 1 :(得分:5)

请注意,我使用的是SHA512,但SHA256可以使用以下示例:

"指定的算法无效"我永远想弄清楚,我几乎尝试了一切。向Gonzalo Gallotti发布道具,发布了帮助我的代码链接。我评论了我的代码以显示每个步骤正在做什么。注意:如果没有在代码示例下面发布的正确生成的证书,此代码将无法运行:

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.");
                }
            }
        }
    }
}

下一步 - 证书必须是SHA512并使用具有SHA512功能的CSP(加密服务提供程序)。以下是CSP及其功能的列表。如果您寻找SHA512,您将找到" Microsoft增强型RSA和AES加密提供商"。默认情况下,生成证书不会使用此功能(至少在Windows中),因此您必须在创建证书时指定它。

创建私钥和证书 - 此步骤将询问您问题,州,地区等等。

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 :(得分:3)

将应用程序从.NET Framework 4.7和更早版本迁移到4.7.1或更高版本时,您可能来过这里。
如果收到异常System.Security.Cryptography.CryptographicException: Invalid algorithm specified.,则原因是针对面向.NET Framework 4.7.1和更高版本(from Microsoft .NET migration guide)的应用程序,默认的SignedXML和SignedXMS算法已更改为SHA256。

在该指南中,您还将找到解决方案:

  

对于面向.NET Framework 4.7.1和更高版本的应用程序,如果不希望使用SHA256,则可以通过将以下配置开关添加到应用程序配置文件的运行时部分中,将默认值还原为SHA1: / p>      

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

但是,这可能并不总是有效,特别是对于Web应用程序,还可以在此blog post中阅读,并附上答案。只需在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);
}

答案 3 :(得分:2)

可以使用certutil工具(在Windows上)检查您的证书使用的CSP

certutil yourCertificate.p12

enter image description here

示例:

  • Microsoft增强加密提供程序v1.0 =>在C#4.7及更高版本中引发错误
  • Microsoft增强型RSA和AES密码提供程序 =>可以使用

答案 4 :(得分:1)

遇到类似的问题,但刚刚解决了。如果你没有使用X509而只是使用普通的RSACryptoServiceProvider来获取密钥,那么只支持SHA1。

答案 5 :(得分:1)

对于点网框架4.7.0或更高版本没有使用sha1,因此请在应用程序启动时配置以下内容。对我来说很好。 AppContext.SetSwitch(“ Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms”,true); AppContext.SetSwitch(“ Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms”,true);

答案 6 :(得分:1)

您可以通过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>

答案 7 :(得分:0)

我通过升级依赖项解决了这个问题。

我没有依赖我之前使用多年的 GAC 版本,而是切换到最新的 NuGet 包 (v16.8.0):

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

这为我们解决了这个问题。