Цифровая подпись SOAP WsSecurity с использованием CXF и WSS4J для 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&#13;
46MBPA/t39pGza/JZfvyApg1VHrMub9d2eRNEJxLbcQTeokJP2Iex07x4cQfIG0N2bYRr1ShgRSI&#13;
V4X8uVaTY1lwqInqHIgSD4WX7nw05V0R/nLAgJEqhxOD3qTRiOdymzlDil79+TjH8cvJpBu/k1Oy&#13;
l9TMJDMKSUT6ShHHCpn6WBNqNOGewJxd8qUq3aj/LgGrj4BvP5xh7dTNUKxLplRzqGyzBz8ZbXpg&#13;
ZeUZR+uTa95+qqgQOqVbwCGU3VGEo2lBjgADVQ==</SignatureValue>
                <KeyInfo>
                    <X509Data>
                        <X509Certificate>MIIEuzCCA6OgAwIBAgIBCjANBgkqhkiG9w0BAQUFADCBoTEcMBoGA1UEBRMTU0UxNjU1NjU5Njgy&#13;
MDItMDAyNDEPMA0GA1UEAxMGZUZhIENBMQswCQYDVQQGEwJTRTESMBAGA1UEBxMJU3RvY2tob2xt&#13;
MQwwCgYDVQQKEwNlRmExDDAKBgNVBAsTA2VGYTEzMDEGCSqGSIb3DQEJARYkZWZhX05PVEFSRUFM&#13;
VVNFUkBlZmFfTk9UQVJFQUxIT1NULnNlMB4XDTE5MDExMTA3MjQ1NFoXDTI5MDEwODA3MjQ1NFow&#13;
</X509Certificate>
                    </X509Data>
                </KeyInfo>
            </Signature>
        </wsse:Security>


person Sukanth Gunda    schedule 28.08.2020    source источник


Ответы (1)


Вы можете использовать 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.

person Alberto Pérez    schedule 08.09.2020