如何在Apache Santuario的KeyInfo中引用证书元素
Apache Santuario 实现KeyInfo引用关联BinarySecurityToken方案
Santuario内置的KeyInfo API只封装了内嵌证书、公钥的快捷添加方法,没有直接提供WS-Security规范下SecurityTokenReference引用结构的封装,要实现目标节点结构,直接手动构造对应DOM节点挂载到KeyInfo实例即可,不需要修改签名核心逻辑,具体实现步骤:
- 提前在WS-Security安全头节点下创建
BinarySecurityToken节点,为其设置全局唯一的ID(即示例中X509-开头的标识),填入Base64编码的X509证书内容,同时配置正确的EncodingType、ValueType属性。 - 初始化签名对象时,正常创建
KeyInfo实例,为其设置对应Id属性,不要调用addX509Certificate这类会内嵌证书的API。 - 手动构造WSSE命名空间下的
SecurityTokenReference节点,设置对应的wsu:Id属性,再在其下创建Reference子节点,配置两个核心属性:URI:值为#拼接前面给BinarySecurityToken设置的IDValueType:值为X509v3令牌对应的规范标识http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3
- 将构造完成的
SecurityTokenReference节点作为未知元素添加到KeyInfo实例,再把KeyInfo绑定到签名对象即可。
核心实现代码参考:
// 提前构造完成的BinarySecurityToken节点及对应ID String bstNodeId = "X509-FBB16D2886CB8FE58213384666945491"; Element binarySecurityToken = /* 提前构造好的BST DOM节点 */; // 初始化KeyInfo KeyInfo keyInfo = new KeyInfo(signatureDoc); keyInfo.setId("KI-FBB16D2886CB8FE58213384666945692"); // 构造SecurityTokenReference节点 Element strNode = signatureDoc.createElementNS( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "wsse:SecurityTokenReference" ); strNode.setAttributeNS( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "wsu:Id", "STR-FBB16D2886CB8FE58213384666945693" ); // 构造STR下的Reference节点 Element strRefNode = signatureDoc.createElementNS( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "wsse:Reference" ); strRefNode.setAttribute("URI", "#" + bstNodeId); strRefNode.setAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" ); strNode.appendChild(strRefNode); // 挂载节点到KeyInfo并绑定到签名对象 keyInfo.addUnknownElement(strNode); signature.getKeyInfo().add(keyInfo.getElement());
注意:如果需要Santuario在校验签名时自动解析这个引用加载证书,需要额外注册对应KeyInfo解析处理器;如果仅需要生成符合结构的签名,上述代码即可满足需求,自定义的KeyInfo子节点不会影响签名计算逻辑。
内容的提问来源于stack exchange,提问作者Sanjaya Liyanage
相关产品推荐
相关产品推荐

