java - SOAP WsSecurity 数字签名使用 CXF 和 WSS4J for X509Certificate
问题描述
想在请求中发送带有 X509Certificate 的出站请求,并使用 CXF 和 WSS4J 验证响应中的数字签名。响应中的 WsSecurity 元素看起来像这样。有没有办法使用 cxf 和 wss4j 验证以下格式的数字签名?尝试了不同的东西,但没有运气。
<wsse:Security>
<wsu:Timestamp wsu:Id="FA_TS-5a00885c-8507-4c5c-b66f-fb45eabcaad6">
<wsu:Created>2020-08-12T12:13:49Z</wsu:Created>
<wsu:Expires>2020-08-12T12:18:49Z</wsu:Expires>
</wsu:Timestamp>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#FA_RIV_1234567890">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>t3/fyodY1azV8CYohUQ79Wi/n3o=</DigestValue>
</Reference>
<Reference URI="#FA_TS-5a00885c-8507-4c5c-b66f-fb45eabcaad6">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>TDEn6ZGMf1HaBiLbCaSs7VzIGzs=</DigestValue>
</Reference>
<Reference URI="#FA_Body_1234567890">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>hBHMEKU7O1eBvxlYlX/t4I9g/S8=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>n5tsEGaXzfnHFy0VvMDdgIGdTjyS3Uwu/b2BnDap0y1qrudSHbfRvA4/tFPEHHiAxFcYDBxcigci
46MBPA/t39pGza/JZfvyApg1VHrMub9d2eRNEJxLbcQTeokJP2Iex07x4cQfIG0N2bYRr1ShgRSI
V4X8uVaTY1lwqInqHIgSD4WX7nw05V0R/nLAgJEqhxOD3qTRiOdymzlDil79+TjH8cvJpBu/k1Oy
l9TMJDMKSUT6ShHHCpn6WBNqNOGewJxd8qUq3aj/LgGrj4BvP5xh7dTNUKxLplRzqGyzBz8ZbXpg
ZeUZR+uTa95+qqgQOqVbwCGU3VGEo2lBjgADVQ==</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIEuzCCA6OgAwIBAgIBCjANBgkqhkiG9w0BAQUFADCBoTEcMBoGA1UEBRMTU0UxNjU1NjU5Njgy
MDItMDAyNDEPMA0GA1UEAxMGZUZhIENBMQswCQYDVQQGEwJTRTESMBAGA1UEBxMJU3RvY2tob2xt
MQwwCgYDVQQKEwNlRmExDDAKBgNVBAsTA2VGYTEzMDEGCSqGSIb3DQEJARYkZWZhX05PVEFSRUFM
VVNFUkBlZmFfTk9UQVJFQUxIT1NULnNlMB4XDTE5MDExMTA3MjQ1NFoXDTI5MDEwODA3MjQ1NFow
</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</wsse:Security>
解决方案
您可以使用Xades4j和迭代签名标签进行验证。
public class AwesomeValidator {
public List<XAdESVerificationResult> validate(Source source) throws XmlValidationException {
try {
XadesVerifier verifier = buildVerifier();
SignatureSpecificVerificationOptions sigOptions = buildVerificationOptions();
NodeList nl = getNodeList(source);
List<XAdESVerificationResult> result = Lists.newArrayList();
for (int i = 0; i < nl.getLength(); i++) {
Element sigElement = (Element)nl.item(i);
try {
result.add(verifier.verify(sigElement, sigOptions));
}
catch (InvalidSignatureException | CertificateValidationException e) {
// throw new CustomException...
}
}
return result;
} catch (XPathExpressionException | XAdES4jException | IOException e) {
// throw new CustomException...
}
}
private XadesVerifier buildVerifier() throws XadesProfileResolutionException {
CertificateValidationProvider certValidationProvider = getAlwaysOkCertificateValidator();
XadesVerificationProfile p = new XadesVerificationProfile(certValidationProvider);
return p.newVerifier();
}
private CertificateValidationProvider getAlwaysOkCertificateValidator() {
return (certSelector, validationDate, otherCerts) -> new ValidationData(Lists.newArrayList(certSelector.getCertificate()));
}
private SignatureSpecificVerificationOptions buildVerificationOptions() {
SignatureSpecificVerificationOptions sigOptions = new SignatureSpecificVerificationOptions();
sigOptions.useResourceResolver(
new org.apache.xml.security.utils.resolver.ResourceResolver(new IdAttrNameResourceResolver()));
return sigOptions;
}
private NodeList getNodeList(Source source) throws XPathExpressionException {
Document document = XmlDocuments.asDom(source);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
xpath.setNamespaceContext(getXadesNamespaceContext());
XPathExpression expr = xpath.compile("//ds:Signature");
return (NodeList) expr.evaluate(document, XPathConstants.NODESET);
}
}
另外,如果要提取证书信息,则需要与证书实体集成并更改CertificateValidationProvider
.
推荐阅读
- javascript - jquery读取txt文件
- r - 在任何滞后有观察后将观察值设置为 NA
- protocol-buffers - 我可以将 gRPC 原型定义组合成多个原型文件吗?
- php - 在mysql中已经创建表后如何使用auto_increment命令?
- c# - 从命令行构建时,如何在程序集中添加一些系统特定版本的 dll?
- reactjs - 如何使用基本http身份验证密码保护托管在firebase中的reactJS网站
- reactjs - 如何将 DefaultValue 放入 CheckboxGroupInput
- excel - 如何删除另一个 Excel 文件的第一行
- c# - 无法从三重奏中获得目标
- python - Python 匹配脚本不返回 True 或 False