我需要用我的.PEM证书和密码在一个XML文件上签名。预期的结果将是以下格式的XML输出文件:
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>zHZj0KS0h60yrhNIijxk0HgKEQI=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>e6ENjwpibfoCkWL13X......</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>BaWgAwIBAgIIUgD9d3AI..</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>但是我不能添加这个标记<X509Certificate>和它的值。我的输出xml文件如下所示:
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>zHZj0KS0h60yrhNIijxk0HgKEQI=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>e6ENjwpibfoCkWL13X......</SignatureValue>
<KeyInfo>
<X509Data>
</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>请查看我在Node.js v16.0.3中的代码:
var select = require('xml-crypto').xpath
, dom = require('xmldom').DOMParser
, SignedXml = require('xml-crypto').SignedXml
, FileKeyInfo = require('xml-crypto').FileKeyInfo
, fs = require('fs')
function signXml(xml, xpath, key, dest) {
var sig = new SignedXml()
sig.signingKey = fs.readFileSync(key)
// not working:
sig.canonicalizationAlgorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
sig.signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
sig.addReference(xpath, ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"])
// working:
// sig.addReference(xpath)
sig.computeSignature(xml)
fs.writeFileSync(dest, sig.getSignedXml())
}
function MyKeyInfo() {
this.getKeyInfo = function(key) {
return "<X509Data></X509Data>"
};
this.getKey = function(keyInfo) {
return fs.readFileSync("certificate.pem", 'utf-8');
};
}
//formatando nota fiscal
var xml = '<ns1:ReqConsultaNotas ' +
'xmlns:ns1="http://localhost:8080/WsNFe2/lote" ' +
'xmlns:tipos="http://localhost:8080/WsNFe2/tp" ' +
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
'xsi:schemaLocation="http://localhost:8080/WsNFe2/lote http://localhost:8080/WsNFe2/xsd/ReqConsultaNotas.xsd">' +
'<Header Id="Consulta:notas">' +
'<Version>1</Version>' +
'</Header>' +
'</ns1:ReqConsultaNotas>'
//sign an xml document
signXml(xml,
"//*[@Id='Consulta:notas']",
"certificate.pem",
"result.xml")
console.log("xml signed succesfully")
var xml = fs.readFileSync("result.xml").toString()
var sig = new SignedXml();
sig.keyInfoProvider = new MyKeyInfo();
//sig.addReference("//*[local-name(.)='InfNfse']");
sig.signingKey = fs.readFileSync("certificate.pem");
sig.computeSignature(xml);
fs.writeFileSync("signed.xml", sig.getSignedXml());如何添加<X509Certificate>标签有什么建议吗?
发布于 2021-07-12 21:58:43
我也在为此而苦苦挣扎,唯一能让我工作的解决方案就是添加这个(你可以在代码中的sig.computeSignature(xml)之前添加它):
sig.keyInfoProvider = {
getKeyInfo: (key, prefix) => {
return `<X509Data><X509SubjectName>${your-cert-CN-data}</X509SubjectName><X509Certificate>${your-public-key}</X509Certificate></X509Data>`;
},
};我不得不使用canonicalizationAlgorithm作为c14n#,然后xml-crypto就不能生成有效的签名了……我已经切换了,现在正在尝试xmldsigjs……
https://stackoverflow.com/questions/68101590
复制相似问题