C#学习教程:如何在C#中将存储在HSM中的私钥转换为SignedXml.SigningKey一些XML签名的演示。我在此链接中发现了一个有趣的示例:使用X509Certificate2签署XML文档并使用PKCS11Interop包装器修改它以使用HSM内的证书和密钥。但是任何人都可以给我一个建议或例子来将ObjectHandleprivateKey从HSM转换为SignedXML.SigningKey列表模板=newList();template.Add(newObjectAttribute(CKA.CKA_CLASS,CKO.CKO_PRIVATE_KEY));template.Add(newObjectAttribute(CKA.CKA_KEY_TYPE,CKK.CKK_RSA));template.Add(newObjectAttribute(CKA.CKA_LABEL,别名));ListfoundObjects=session.FindAllObjects(template);ObjectHandleprivateKey=foundObjects[0];signedXml.SigningKey=privateKey;//这是我卡住的地方。在上面的外部链接示例中。他们使用带有组合私钥的证书。然后他们可以像这样使用。signedXml.SigningKey=cert.PrivateKey;但是我使用的证书不包含私钥。请给我一些建议。您需要实现从System.Security.Cryptography.Xml.SignedXmlinheritance的自定义类).GetMethod("BuildDigestedReferences",BindingFlags.Instance|BindingFlags.NonPublic);methodInfo.Invoke(this,null);SignedInfo.SignatureMethod=XmlDsigRSASHA1Url;//查看Config文件中是否定义了签名描述类SignatureDescriptionsignatureDescription=CryptoConfig.CreateFromName(SignedInfo.SignatureMethod)asSignatureDescription;如果(signatureDescription==null)thrownewCryptographicException("Cryptography_Xml_SignatureDescriptionNotCreated");varhashAlg=signatureDescription.CreateDigest();如果(hashAlg==null)抛出新的CryptographicException(“Cryptography_Xml_CreateHashAlgorithmFailed”);varmethodInfo2=typeof(SignedXml).GetMethod("GetC14NDigest",BindingFlags.Instance|BindingFlags.NonPublic);varhashvalue=(byte[])methodInfo2.Invoke(this,newobject[]{hashAlg});m_signature.SignatureValue=signerProvider.Sign(哈希值);}}然后你需要创建这样的界面publicinterfaceISignerProvider{byte[]Sign(byte[]data);}然后像这样通过Pkcs11Interop实现publicclassPkcs11SignerProvider:ISignerProvider{privatestring_thumbprint;公共字符串DllPath{得到;放;}publicstringTokenSerial{get;放;}publicstringTokenPin{get;放;}公共字符串PrivateKeyLabel{得到;放;}publicPkcs11SignerProvider(stringdllPath,stringtokenSerial,stringtokenPin,stringprivateKeyLabel){DllPath=dllPath;令牌序列号=令牌序列号;TokenPin=tokenPin;PrivateKeyLabel=privateKeyLabel;}publicbyte[]Sign(byte[]data){using(varpkcs11=newPkcs11(DllPath,AppType.SingleThreaded)){varslots=pkcs11.GetSlotList(SlotsType.WithTokenPresent);varslot=slots.FirstOrDefault(slot1=>slot1.GetTokenInfo().SerialNumber==TokenSerial);if(slot==null)thrownewException("没有序列号令牌"+TokenSerial);使用(varsession=slot.OpenSession(SessionType.ReadOnly)){session.Login(CKU.CKU_USER,TokenPin);varsearchTemplate=newList{newObjectAttribute(CKA.CKA_CLASS,CKO.CKO_PRIVATE_KEY),newObjectAttribute(CKA.CKA_KEY_TYPE,CKK.CKK_RSA)};如果(!string.IsNullOrEmpty(PrivateKeyLabel))searchTemplate.Add(newObjectAttribute(CKA.CKA_LABEL,PrivateKeyLabel));varfoundObjects=session.FindAllObjects(searchTemplate);varprivateKey=foundObjects.FirstOrDefault();使用(varmechanism=newMechanism(CKM.CKM_RSA_PKCS)){returnsession.Sign(mechanism,privateKey,data);}}}}}然后调整使用这种方法来签名xmlpublicstaticvoidSign(XmlDocumentxmlDoc,ISignerProvidersignerProvider){if(xmlDoc==null)thrownewArgumentException("xmlDoc");如果(xmlDoc.DocumentElement==null)thrownewArgumentException("xmlDoc.DocumentElement");varsignedXml=newCustomSignedXml(xmlDoc);varreference=newReference{Uri=""};varenv=newXmlDsigEnvelopedSignatureTransform();reference.AddTransform(env);signedXml.AddReference(reference);signedXml.ComputeSignature(signerProvider);varxmlDigitalSignature=signedXml.GetXml();xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature,true));}并且这部分代码要验证publicstaticboolVerify(XmlDocumentdocument,X509Certificate2certificate){//检查参数。if(document==null)thrownewArgumentException("Doc");if(certificate==null)thrownewArgumentException("Key");//创建一个新的SignedXml对象并传递给它//XML文档class.varsignedXml=newSignedXml(document);//找到“签名”节点并创建一个新的//XmlNodeList对象。varnodeList=document.GetElementsByTagName("Signature");//如果没有找到签名则抛出异常.if(nodeList.Count=2){抛出新的CryptographicException("验证失败:为文档找到了不止一个签名。");}//加载第一个节点。已签名的Xml。LoadXml((XmlElement)nodeList[0]);返回signedXml。检查签名(证书,真);你需要实现一个继承自System.Security.Cryptography.RSA类的自定义类,在其实现中使用Pkcs11Interop,然后使用自定义类的一个实例作为SigningKey,你可以自己实现,也可以使用Pkcs11Interop。X509Store库,该库提供了一个易于使用的基于PKCS#11的X.509证书存储,并包括一个继承自System.Security.Cryptography.RSA类的Pkcs11RsaProvider类。还有一个代码示例可以演示它在SignedXml类中的用法。以上是C#学习教程:如何将存储在HSM中的私钥转换为C#中的SignedXml.SigningKey。如果对你有用,需要进一步了解C#学习教程,希望大家多加关注——本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
