XAdES 验证失败,引用 URI= " " 对于具有样式表处理指令的文档



我正在签署的文档如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="CDA_PL_IG_1.3.1.xsl" type="text/xsl"?>
<ClinicalDocument></ClinicalDocument>

我正在使用xadesjs使用以下代码对此 XML 进行签名:

const crypto = new Crypto();
xadesjs.Application.setEngine('NodeJS', crypto);
export async function sign(xml: string, { publicKey, privateKey }: any) {
const hash = 'SHA-1';
const alg = {
name: 'RSASSA-PKCS1-v1_5',
hash
};
const keyDer = pem2der(privateKey.toString());
const key = await crypto.subtle.importKey('pkcs8', keyDer, alg, true, [ 'sign' ]);
const parsed = xadesjs.Parse(xml.trim());
const xadesXml = new xadesjs.SignedXml();
const signature = await xadesXml.Sign(alg, key, parsed, {
signingCertificate: preparePem(publicKey.toString()),
references: [ { uri: '', hash, transforms: [ 'enveloped' ] } ],
x509: [ preparePem(publicKey.toString()) ]
});
parsed.documentElement.appendChild(signature.GetXml()!);
return parsed.toString();
}
function preparePem(pem: string) {
return pem.replace(/-----(BEGIN|END)[wds]+-----/g, '').replace(/[rn]/g, '');
}
function pem2der(pem: string) {
pem = preparePem(pem);
return new Uint8Array(Buffer.from(pem, 'base64')).buffer;
}

仅当我删除 xml 声明和样式表指令时,生成的签名才有效。因此,只有对此进行签名才会返回正确签名的文档:

<ClinicalDocument></ClinicalDocument>

签署此

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="CDA_PL_IG_1.3.1.xsl" type="text/xsl"?>
<ClinicalDocument></ClinicalDocument>

错误,消息指出未对整个文档进行签名。

我认为问题出在URI=""引用上。它只对<ClinicalDocument>进行签名,<?xml version><?xml-stylesheet>没有签名。

我如何签署所有内容?

在签署文档之前,您需要对文档进行规范化 (C14N(。我不能评论使用 xadesjs,但这里有一些一般建议。

对于 Xades 签名,您需要计算三个部分的消息摘要,所有部分都是 C14N 编辑的。

(1( 不包括ds:Signature元素的完整文档 - 这为您提供了URI=""引用的摘要值。

(2(xades:SignedProperties元素的子集,它需要从完整文档继承任何命名空间。这将提供"已签名属性"引用的摘要值。

(3(ds:SignedInfo元素的最后一个子集,同样需要包含继承的命名空间 - 此值间接用于计算签名值。

始终排除<?xml version>。在计算信封签名的摘要值(引用 URI="(时,包括该<?xml-stylesheet>,但在对两个子集进行 C14N时排除该

计算 C14n 变换并非易事。我将在这里插入我自己的规范化实用程序,SC14N https://www.cryptosys.net/sc14n/。

您可以直接生成摘要值,如下所示:

sc14n -d -x ds:Signature clindoc.xml
sc14n -d -s xades:SignedProperties clindoc.xml
sc14n -d -s ds:SignedInfo clindoc.xml

要查看 C14N 输出,请省略 -d 选项

sc14n  -x ds:Signature clindoc.xml
<?xml-stylesheet href="CDA_PL_IG_1.3.1.xsl" type="text/xsl"?>
<ClinicalDocument ...>

请注意,<xml-stylesheet行包含在自己的行中。