c# – SignedXml计算签名与SHA256
我正在尝试使用SHA256对
XML文档进行数字签名.
我试图用这个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();.谁能告诉我我做错了什么? 解决方法
X509Certificate2将私钥从pfx文件加载到不支持SHA-256的Microsoft Enhanced Cryptographic Provider v1.0(提供商类型1 a.k.a. PROV_RSA_FULL)中.
基于CNG的加密提供程序(在Vista和Server 2008中引入)支持比基于CryptoAPI的提供程序更多的算法,但是.NET代码似乎还在使用基于CryptoAPI的类,如RSACryptoServiceProvider而不是RSACng,所以我们必须解决这些限制. 但是,另一个CryptoAPI提供程序,Microsoft增强型RSA和AES加密提供程序(提供者类型24 a.k.a. PROV_RSA_AES)支持SHA-256.所以如果我们把这个私钥加入这个提供者,我们可以用它签名. 首先,您必须调整X509Certificate2构造函数,以便将密钥从X509Certificate2将其引入的提供者中导出,方法是添加X509KeyStorageFlags.Exportable标志: X509Certificate2 cert = new X509Certificate2( @"location of pks file","password",X509KeyStorageFlags.Exportable); 并导出私钥: var exportedKeyMaterial = cert.PrivateKey.ToXmlString( /* includePrivateParameters = */ true); 然后为支持SHA-256的提供程序创建一个新的RSACryptoServiceProvider实例: var key = new RSACryptoServiceProvider( new CspParameters(24 /* PROV_RSA_AES */)); key.PersistKeyInCsp = false; 并导入私钥: key.FromXmlString(exportedKeyMaterial); 当您创建了SignedXml实例时,请告诉它使用密钥而不是cert.PrivateKey: signedXml.SigningKey = key; 它现在可以工作. 以下是MSDN上的list of provider types and their codes. 以下是您的示例的完整调整代码: CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription),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,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(); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |