【发布时间】:2022-07-25 03:57:50
【问题描述】:
我正在尝试创建一个签名的 XML 发布请求。 XML 需要在请求的正文中发送。 签名需要具备以下条件:
- 摘要需要具有包容性规范化算法
- 签名需要有专属的规范化算法
- 必须使用语法封装签名
- SHA-256 需要用于散列
- 数字签名需为2048位的RSAWithSHA256算法
- 指纹需要是 X.509 证书。指纹计算公式如下:HEX(SHA-1(DER certificate))
所有这些要求都直接来自文档。
我使用 xml-crypto 来签署 XML .cer en .pem 文件是使用以下命令创建的:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.pem -out certificate.cer
下面的代码用于签署 XML。
const xml = `<?xml version="1.0" encoding="UTF-8"?>
<someTag xmlns="some_url" version="3.3.1">
<createDateTimestamp>${new Date().toISOString()}</createDateTimestamp>
<anotherTag>
<id>${id}</id>
<subID>0</subID>
</anotherTag>
</someTag>`;
try {
// certificate file
const cer = Buffer.from((await bucket.file(`certificates/certificate.crt`).download())[0]).toString('base64');
logger.log('pem', cer.toString());
const cerShasum = crypto.createHash('sha1');
cerShasum.update(cer);
// private key file
const pem = Buffer.from((await bucket.file(`certificates/privateKey.pem`).download())[0]);
logger.log('pem', pem.toString());
// const decryptedKey = forge.pki.decryptRsaPrivateKey(pem.toString('ascii'), pemPassphrase);
// const decryptedKeyBuffer = Buffer.from(forge.pki.privateKeyToPem(decryptedKey), 'ascii');
// logger.log('decryptedKeyBuffer', decryptedKeyBuffer.toString());
// sign xml document
const sig = new SignedXml();
sig.signingKey = pem;
sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; // set signing algorithme
sig.addReference('//*[local-name()="someTag"]', ['http://www.w3.org/2000/09/xmldsig#enveloped-signature'], 'http://www.w3.org/2001/04/xmlenc#sha256');
sig.keyInfoProvider = new FileKeyInfo();
logger.log('xml', xml);
sig.computeSignature(xml);
let postData = sig.getSignedXml();
postData = postData.replace('<X509Data/>', `<KeyName>${cerShasum.digest('hex')}</KeyName>`).replace('#_0', '').replace('Id="_0"', '').trim();
logger.log('postData', postData);
// sent req
const url = host;
const result = await axios.post(url, postData);
logger.log('result', result);
logger.log('res.data', result.data);
const resDataJson = await parseStringPromise(result.data);
logger.log('resDataJson', resDataJson);
} catch (e) {
logger.error('error: ', e);
}
我得到的错误:
<Error>
<errorCode>SE2000</errorCode>
<errorMessage>Authentication error</errorMessage>
<errorDetail>Field generating error: Signature</errorDetail>
</Error>
当我尝试向检查器验证签名时,我收到以下错误
func=xmlSecOpenSSLEvpDigestVerify:file=digests.c:line=279:obj=sha256:subj=unknown:error=12:invalid data:data and digest do not match
RESULT: Signature is INVALID
是DigestValue没有正确生成的问题吗?
有人看到我做错了吗?
【问题讨论】:
标签: node.js xml xml-signature