首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用NodeJS用我的.PEM证书对XML文件签名

使用NodeJS用我的.PEM证书对XML文件签名
EN

Stack Overflow用户
提问于 2021-06-23 22:14:24
回答 1查看 454关注 0票数 0

我需要用我的.PEM证书和密码在一个XML文件上签名。预期的结果将是以下格式的XML输出文件:

代码语言:javascript
复制
<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文件如下所示:

代码语言:javascript
复制
<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中的代码:

代码语言:javascript
复制
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>标签有什么建议吗?

EN

回答 1

Stack Overflow用户

发布于 2021-07-12 21:58:43

我也在为此而苦苦挣扎,唯一能让我工作的解决方案就是添加这个(你可以在代码中的sig.computeSignature(xml)之前添加它):

代码语言:javascript
复制
sig.keyInfoProvider = {
getKeyInfo: (key, prefix) => {
    return `<X509Data><X509SubjectName>${your-cert-CN-data}</X509SubjectName><X509Certificate>${your-public-key}</X509Certificate></X509Data>`;
  },
};

我不得不使用canonicalizationAlgorithm作为c14n#,然后xml-crypto就不能生成有效的签名了……我已经切换了,现在正在尝试xmldsigjs……

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68101590

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档