Javascript XAdES验证失败,引用URI="&引用;用于带有样式表处理指令的文档

Javascript XAdES验证失败,引用URI="&引用;用于带有样式表处理指令的文档,javascript,xml,cryptography,digital-signature,xades,Javascript,Xml,Cryptography,Digital Signature,Xades,我正在签署的文件如下所示 我正在使用xadesjs使用以下代码对该XML进行签名: const crypto=new crypto(); xadesjs.Application.setEngine('NodeJS',crypto); 导出异步函数符号(xml:string,{publicKey,privateKey}:any){ 常量散列='SHA-1'; 常数alg={ 名称:“RSASSA-PKCS1-v1_5”, 搞砸 }; const-keyDer=pem2der(privateKe

我正在签署的文件如下所示


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

const crypto=new crypto();
xadesjs.Application.setEngine('NodeJS',crypto);
导出异步函数符号(xml:string,{publicKey,privateKey}:any){
常量散列='SHA-1';
常数alg={
名称:“RSASSA-PKCS1-v1_5”,
搞砸
};
const-keyDer=pem2der(privateKey.toString());
const key=await crypto.minute.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{
签名证书:preparePem(publicKey.toString()),
引用:[{uri:'',哈希,转换:['enveloped']}],
x509:[preparePem(publicKey.toString())]
});
parsed.documentElement.appendChild(signature.GetXml()!);
返回已解析的.toString();
}
函数preparePem(pem:字符串){
返回pem.replace(/---(BEGIN | END)[\w\d\s]+----/g',)。replace(/[\r\n]/g',);
}
函数pem2der(pem:字符串){
pem=预处理pem(pem);
返回新的Uint8Array(Buffer.from(pem,'base64')).Buffer;
}
只有删除xml声明和样式表指令,生成的签名才有效。因此,只有对此进行签名才能返回正确签名的文档:

<ClinicalDocument></ClinicalDocument>

签字


消息中出现错误,表示未对整个文档进行签名

我假设问题在于
URI=”“
引用。它只对
进行签名,而对
不进行签名

如何签名?

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

对于Xades签名,您需要计算三个部分的消息摘要,它们都是C14N-ed

(1) 不包括
ds:Signature
元素的完整文档-这将为
URI=”“
引用提供摘要值

(2)
xades:SignedProperties
元素的子集,它需要从完整文档继承任何名称空间。这将为SignedProperties引用提供摘要值

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

始终排除
在计算封装签名的摘要值(参考URI=“”)时包括在内,但在对两个子集进行C14N运算时不包括在内

计算C14n变换不是一件小事。我将在这里插入自己的规范化实用程序SC14N

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

sc14n -d -x ds:Signature clindoc.xml
sc14n -d -s xades:SignedProperties clindoc.xml
sc14n -d -s ds:SignedInfo clindoc.xml
要查看C14N ed输出,请省略-d选项

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

请注意,
年前,当我研究xades时,我无法在根xml元素之外签名。如果你想要一个精确的符号,每个字节一个字节,为什么不使用CADES呢?只有我的2%幸运的是,签名不是我的事。我必须用XADES来做这个。非常感谢你的回答。经过进一步研究,它看起来像xmldsigjs库中的规范化过程中的一个bug,它是xadesjs的直接依赖项,负责规范化过程。