人们,
我已经阅读了此处的帖子和使用 JAXB 时处理数字签名的示例代码,并且遇到了一个问题,我认为这是通过 JAXB 编组将名称空间引入“SignedInfo”元素的问题。
我已经定义了一个 XSD,它将被以不同编程语言实现的多个应用程序使用。我将 XSD 编译为 JAXB 注释类以供我的实现使用(Jersey JAX-RS 和 JAX-WS)。我目前的流程如下:
- JAXB 对象是使用适当的数据创建的或从远程应用程序交付的。
- 如Blaise Doughan所述,将 JAXB 分配到 DOM 以进行签名。
- 使用创建封装签名的私钥签署 DOM。
- 将 DOM 解组到 JAXB 以用于 JAX-RS/WS 消息传递。
我被迫在我的 XSD 定义中的父元素末尾添加一个“xsd:any”元素,以便 DOM 到 JAXB 解组工作,否则嵌入的“签名”元素被删除。我还让 JAXBContext 知道 xmldsig 命名空间。
以下步骤顺序有效:JAXB -> DOM -> 签名 -> 验证
所以我知道签名工作正常。但是,以下序列验证失败:JAXB -> DOM -> 签名 -> JAXB -> DOM ->Validate
经过一些测试和阅读后,我的猜测是 JABX Marshaller 对“SignedInfo”的修改导致了问题,因为它为所有 xmlsig 元素添加了命名空间前缀。
这是 DOM 生成的 XML(缩写):
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
<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"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
<DigestValue>...</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
<KeyInfo>
<X509Data>
<X509SubjectName>...</X509SubjectName>
<X509Certificate>...</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
这是从 JAXB 编组后的元素(ns2 在父元素中定义):
<ns2:Signature>
<ns2:SignedInfo>
<ns2:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
<ns2:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ns2:Reference URI="">
<ns2:Transforms>
<ns2:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</ns2:Transforms>
<ns2:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
<ns2:DigestValue>...</ns2:DigestValue>
</ns2:Reference>
</ns2:SignedInfo>
<ns2:SignatureValue>...</ns2:SignatureValue>
<ns2:KeyInfo>
<ns2:X509Data>
<ns2:X509SubjectName>...</ns2:X509SubjectName>
<ns2:X509Certificate>...</ns2:X509Certificate>
</ns2:X509Data>
</ns2:KeyInfo>
</ns2:Signature>
我的假设是否正确,这是验证失败的原因?
有没有办法在使用 JAXB 时保持“签名”元素不变?
是否有一个 CanonicalizationMethod 会忽略计算中的任何命名空间前缀?
此外,如果要更改已签名 XML 中的命名空间前缀,这是否也会导致验证失败(例如,从 ns1 更改为 abc)?我想知道如果其他应用程序序列化/反序列化 XML 并可能更改命名空间前缀,数字签名是否会失效?
感谢您的任何帮助!
约翰