使用xml-crypto库签名XML时遭遇XPath解析错误求助
用xml-crypto签名XML时遇到XPath解析错误
我尝试使用xml-crypto库对XML中的<title>节点进行签名,但执行时抛出了XPath解析错误,甚至运行官方示例代码也出现完全相同的报错。
我的代码
const fs = require("fs"); const xmlCrypto = require("xml-crypto"); const xpath = require("xpath"); const dom = require("xmldom").DOMParser; var xml = "<book><title>Harry Potter</title></book>"; var xmlDocument = new dom().parseFromString(xml, "text/xml"); var node = xpath.select("//title", xmlDocument)[0]; console.log(node.localName + ": " + node.firstChild.data); console.log("Node: " + node.toString()); const privateKey = fs.readFileSync( "./certifications/universal-pk.pem", "utf-8" ); console.log("privateKey", privateKey); const reference = { uri: "", transforms: ["canonicalize", "c14n"], digestAlgorithm: "http://www.w3.org/2001/04/xmlenc#sha256", }; const sig = new xmlCrypto.SignedXml(); sig.addReference(reference); sig.signingKey = privateKey; sig.computeSignature(node);
控制台输出
title: Harry Potter Node: <title>Harry Potter</title> privateKey -----BEGIN PRIVATE KEY----- ....... -----END PRIVATE KEY----- [xmldom error] invalid doc source @#[line:0,col:undefined] \api\node_modules\xml-crypto\node_modules\xpath\xpath.js:1278 throw new Error("XPath parse error"); ^ Error: XPath parse error
问题原因及解决办法
1. 传递完整XML文档而非单个节点
computeSignature方法设计为操作完整XML文档,而非单独节点。修改代码,传入完整文档并通过引用指定目标节点:
// 初始化SignedXml时传入完整文档 const sig = new xmlCrypto.SignedXml(xmlDocument); // 给title节点添加唯一ID,用于引用 node.setAttribute("Id", "target-title"); const reference = { uri: "#target-title", // 通过ID引用目标节点 transforms: [ "http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" ], digestAlgorithm: "http://www.w3.org/2001/04/xmlenc#sha256", }; sig.addReference(reference); sig.signingKey = privateKey; sig.computeSignature(); // 输出签名后的XML console.log(sig.getSignedXml());
2. 升级依赖解决版本兼容性
xml-crypto旧版本依赖的xpath、xmldom库存在兼容性问题,升级到最新版本可解决:
npm install xml-crypto@latest xpath@latest xmldom@latest
若升级后仍有问题,可锁定兼容版本:
{ "dependencies": { "xml-crypto": "^2.1.3", "xpath": "^0.0.33", "xmldom": "^0.6.0" } }
3. 验证私钥格式
确保私钥为PKCS#8格式(以-----BEGIN PRIVATE KEY-----开头),若为PKCS#1格式(-----BEGIN RSA PRIVATE KEY-----),需转换为PKCS#8后再使用。
内容的提问来源于stack exchange,提问作者PingWinLqD
相关产品推荐
相关产品推荐

