C# 为什么我会得到;指定的算法无效";例外

C# 为什么我会得到;指定的算法无效";例外,c#,cryptography,C#,Cryptography,这是我的密码 X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password"); RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey; string id = CryptoConfig.MapNameToOID("SHA256"); return csp.SignData(File.ReadAllBytes(file

这是我的密码

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
在最后一行,我得到了一个例外:

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.CryptographyException“指定的算法无效。”

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

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

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

id=2.16.840.1.101.3.4.2.1

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

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

您的问题是CSP不支持SHA256。您可以获得更多信息

注意,我使用SHA512,但SHA256将使用以下示例:

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
“指定的算法无效”花了我很长时间才弄明白,我几乎什么都试过了

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
步骤1-证书必须是SHA512,并使用支持SHA512的CSP(加密服务提供商)。以下是CSP及其功能的列表。如果您查找SHA512,您将找到“Microsoft增强的RSA和AES加密提供程序”。默认情况下,生成证书不使用此选项(至少在Windows中),因此在创建证书时必须指定此选项

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
如果使用openssl创建证书,则可以使用下面的选项-CSP来设置正确的CSP,以使其正常工作。如果您有一个现有的pfx,您可以使用openssl将其转换为PEM文件,然后返回到pfx以添加该选项

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
创建私钥和证书-此步骤将询问您的问题、州、地区等

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
openssl req -x509 -nodes -sha512 -newkey rsa:2048 -keyout 512key.pem -out 512cert.pem -days 3650
使用Microsoft增强的RSA和AES加密提供程序创建要导入到证书存储中的PFX文件:

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
openssl pkcs12 –export –in 512cert.pem –inkey 512key.pem –CSP “Microsoft Enhanced RSA and AES Cryptographic Provider” –out 512pfx.pfx
第2步:感谢Gonzalo Gallotti发布了帮助我的代码链接。我对代码进行了注释,以显示每个步骤都在做什么。注意:如果没有步骤1中描述的正确生成的证书,此代码将无法工作

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
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.");
                }
            }
        }
    }
}

有一个类似的问题,但刚刚解决。如果您不是使用X509,而是仅使用普通RSACryptServiceProvider来获取密钥,则仅支持SHA1。

对于dot net framework 4.7.0或更高版本,不使用SHA1,因此请在应用程序启动中配置以下内容。这对我很有效

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
 AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
 AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);

您可能是在将应用程序从.NET Framework 4.7及早期版本迁移到4.7.1或更高版本时来到这里的。
如果收到异常
System.Security.Cryptography.Cryptography异常:指定的算法无效。
,原因是针对.NET Framework 4.7.1及更高版本()的应用程序的默认SignedXML和SignedXMS算法更改为SHA256

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
在该指南中,您还可以找到解决方案:

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
对于以.NET Framework 4.7.1及更高版本为目标的应用程序,如果不希望使用SHA256,可以通过将以下配置开关添加到应用程序配置文件的运行时部分,将默认值还原为SHA1:

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
,幸运的是还有答案。只需在
应用程序\u Start

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
受保护的无效应用程序\u启动(对象发送方,事件参数e)
{
[...]
SetSwitch(“Switch.System.Security.Cryptography.Xml.UseSecureHashAlgorithms”,true);
SetSwitch(“Switch.System.Security.Cryptography.Pkcs.UseSecureHashAlgorithms”,true);
}

您可以通过appSettings在web配置中设置AppContext开关:

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
<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>

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

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

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

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
  • Microsoft Enhanced Cryptographic Provider v1.0=>在C#4.7及以上版本中抛出错误
  • Microsoft增强的RSA和AES加密提供程序=>有效

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

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);
我不再依赖以前使用多年的GAC版本,而是转而使用最新的NuGet软件包(v16.8.0),包括:

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

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

我用id的值更新了问题。请尝试使用pXCert.GetRSAPrivateKey()instead@thangcao谢谢你的帮助,我工作得很有魅力是@thangcao,救生圈评论!我还要补充一点,在2020年,对于.NET 4.6及更高版本,RSA本身支持SignData,比如:((RSA)cert.GetRSAPrivateKey()).SignData(bytes,HashAlgorithmName.SHA512,rsAsignatureAdding.Pkcs1)有什么办法可以做到这一点吗?我正在从java移植它,它需要使用相同的算法。据我所知,它使用的是rsa+SHA,您可能需要检查一下.Net Framework中的SHA256类。但是,我没有使用它。SHA256CryptoServiceProvider不接受非对称密钥此版本仅支持SHA-256用于对称密钥使用,例如Kerberos密钥,并且不使用X.509证书对消息进行签名。WCF不支持使用SHA-256散列的RSA签名(在X.509证书中使用),因为目前在.NET Framework 3.0(源:)中不支持RSA-SHA256。不确定这是为了什么。。这当然对我有帮助,非常感谢+1 +1@TjadClark开头的冗长代码隐藏了答案的最后一部分,它描述了正确的操作!我将编辑以更正此问题
X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);