使用SHA256的SignedXml计算签名 [英] SignedXml Compute Signature with SHA256

查看:183
本文介绍了使用SHA256的SignedXml计算签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用SHA256对XML文档进行数字签名。

I am trying to digitally sign a XML document using SHA256.

我正在尝试使用 Security.Cryptography.dll

这是我的代码-

CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription),"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

X509Certificate2 cert = new X509Certificate2(@"location of pks file", "password");
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(@"input.xml");

SignedXml signedXml = new SignedXml(doc);
signedXml.SigningKey = cert.PrivateKey;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

// 
// Add a signing reference, the uri is empty and so the whole document 
// is signed. 
Reference reference = new Reference();
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
reference.Uri = "";
signedXml.AddReference(reference);

// 
// Add the certificate as key info, because of this the certificate 
// with the public key will be added in the signature part. 
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
// Generate the signature. 
signedXml.ComputeSignature();

但是我收到指定了无效的算法。 signedXml.ComputeSignature(); 错误。有人可以告诉我我在做什么错吗?

But i am getting "Invalid algorithm specified." error at signedXml.ComputeSignature();. Can anyone tell me what I am doing wrong?

推荐答案

X509Certificate2 加载从pfx文件到 Microsoft增强加密提供程序v1.0 中的私钥(提供程序类型 1 aka PROV_RSA_FULL ),不支持SHA-256。

X509Certificate2 loads the private key from the pfx file into the Microsoft Enhanced Cryptographic Provider v1.0 (provider type 1 a.k.a. PROV_RSA_FULL) which doesn't support SHA-256.

基于CNG的密码提供程序(在Vista和Server 2008中引入)比CryptoAPI支持更多算法基于.NET的提供程序,但.NET代码似乎仍可与基于CryptoAPI的类一起使用,例如 RSACryptoServiceProvider 而不是 RSACng 因此我们必须解决这些限制。

The CNG-based cryptographic providers (introduced in Vista and Server 2008) support more algorithms than the CryptoAPI-based providers, but the .NET code still seems to be working with CryptoAPI-based classes like RSACryptoServiceProvider rather than RSACng so we have to work around these limitations.

但是,另一个CryptoAPI提供程序 Microsoft增强型RSA和AES加密提供程序(提供程序类型 24 aka PROV_RSA_AES )确实支持SHA-256。因此,如果我们将私钥输入到此提供程序中,则可以对其进行签名。

However, another CryptoAPI provider, Microsoft Enhanced RSA and AES Cryptographic Provider (provider type 24 a.k.a. PROV_RSA_AES) does support SHA-256. So if we get the private key into this provider, we can sign with it.

首先,您必须调整您的 X509Certificate2 构造函数,通过添加 X509KeyStorageFlags.Exportable X509Certificate2 放入的提供程序中导出。 c $ c>标志:

First, you'll have to adjust your X509Certificate2 constructor to enable the key to be exported out of the provider that X509Certificate2 puts it into by adding the X509KeyStorageFlags.Exportable flag:

X509Certificate2 cert = new X509Certificate2(
    @"location of pks file", "password",
    X509KeyStorageFlags.Exportable);

并导出私钥:

var exportedKeyMaterial = cert.PrivateKey.ToXmlString(
    /* includePrivateParameters = */ true);

然后为一个新的 RSACryptoServiceProvider 实例创建一个支持SHA-256的提供程序:

Then create a new RSACryptoServiceProvider instance for a provider that supports SHA-256:

var key = new RSACryptoServiceProvider(
    new CspParameters(24 /* PROV_RSA_AES */));
key.PersistKeyInCsp = false;

并将私钥导入到其中:

key.FromXmlString(exportedKeyMaterial);

创建 SignedXml 实例后,告诉它使用 key 而不是 cert.PrivateKey

When you've created your SignedXml instance, tell it to use key rather than cert.PrivateKey:

signedXml.SigningKey = key;

现在可以使用了。

这是提供商类型列表和他们的代码在MSDN上。

以下是您示例的完整调整后代码:

Here's the full adjusted code for your example:

CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

X509Certificate2 cert = new X509Certificate2(@"location of pks file", "password", X509KeyStorageFlags.Exportable);

// Export private key from cert.PrivateKey and import into a PROV_RSA_AES provider:
var exportedKeyMaterial = cert.PrivateKey.ToXmlString( /* includePrivateParameters = */ true);
var key = new RSACryptoServiceProvider(new CspParameters(24 /* PROV_RSA_AES */));
key.PersistKeyInCsp = false;
key.FromXmlString(exportedKeyMaterial);

XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(@"input.xml");

SignedXml signedXml = new SignedXml(doc);
signedXml.SigningKey = key;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

// 
// Add a signing reference, the uri is empty and so the whole document 
// is signed. 
Reference reference = new Reference();
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
reference.Uri = "";
signedXml.AddReference(reference);

// 
// Add the certificate as key info, because of this the certificate 
// with the public key will be added in the signature part. 
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
// Generate the signature. 
signedXml.ComputeSignature();

这篇关于使用SHA256的SignedXml计算签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆