首页 > 解决方案 > 如何诊断/修复 Web 服务响应上的签名摘要验证失败?

问题描述

我正在使用 wss4jSecurityInterceptor 对我的 web 服务进行验证和保护操作。来回的 SOAP 消息通过签名、加密和时间戳进行保护。我遇到的问题是,收件人无法验证我的响应签名并收到以下错误:

oracle.wsm.security.SecurityException:WSM-00061:签名摘要验证失败。系统属性 xml.debug.verify 应该在验证阶段启用有关摘要计算的详细信息(注意 xml.debug.verify 会减慢非常大的消息的签名验证速度)。

这是我用来执行验证和安全操作的代码:

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
    private static Log log = LogFactory.getLog(WebServiceConfig.class);
    @Bean
    public KeyStoreCallbackHandler securityCallbackHandler() {
        KeyStoreCallbackHandler callbackHandler = new KeyStoreCallbackHandler();
        callbackHandler.setPrivateKeyPassword("changeit");
        return callbackHandler;
    }
@Bean
public Wss4jSecurityInterceptor securityInterceptor() throws Exception {
    Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();
    // validate incoming request
    securityInterceptor.setValidationActions("Timestamp Signature Encrypt");
    securityInterceptor.setValidationSignatureCrypto(getCryptoFactoryBean().getObject());
    securityInterceptor.setValidationDecryptionCrypto(getCryptoFactoryBean().getObject());
    securityInterceptor.setValidationCallbackHandler(securityCallbackHandler());

    // encrypt the response
    securityInterceptor.setSecurementEncryptionUser("client_pub"); // alias of client public key
    securityInterceptor.setSecurementEncryptionParts("{Content}{}Body");

    securityInterceptor.setSecurementEncryptionKeyIdentifier("DirectReference");
    securityInterceptor.setSecurementEncryptionCrypto(getCryptoFactoryBean().getObject());

    // sign the response
    securityInterceptor.setSecurementSignatureAlgorithm(WSS4JConstants.RSA_SHA1);
    securityInterceptor.setSecurementSignatureDigestAlgorithm(WSS4JConstants.SHA1);
    securityInterceptor.setSecurementSignatureKeyIdentifier("DirectReference");
    securityInterceptor.setSecurementActions("Encrypt Signature Timestamp");
    securityInterceptor.setSecurementUsername("secret"); // alias of the private key
    securityInterceptor.setSecurementPassword("changeit");
    securityInterceptor.setSecurementSignatureCrypto(getCryptoFactoryBean().getObject());

    return securityInterceptor;
}
@Bean
public CryptoFactoryBean getCryptoFactoryBean() throws IOException {
    CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
    cryptoFactoryBean.setKeyStorePassword("changeit");
    cryptoFactoryBean.setKeyStoreLocation(new ClassPathResource("cert/myKeystore.jks"));
    return cryptoFactoryBean;
}

@Override
    public void addInterceptors(List<EndpointInterceptor> interceptors) {
        try {
            interceptors.add(securityInterceptor());
        } catch (Exception e) {
            throw new RuntimeException("could not initialize security interceptor");
        }
    }

@Bean
public ServletRegistrationBean<MessageDispatcherServlet> registerMessageDispatcherServlet(
        ApplicationContext context) {

    MessageDispatcherServlet messageDispatcherServlet = new MessageDispatcherServlet();
    messageDispatcherServlet.setApplicationContext(context);
    messageDispatcherServlet.setTransformWsdlLocations(true);
    return new ServletRegistrationBean<MessageDispatcherServlet>(messageDispatcherServlet, "/ws/*");
}

接收方怀疑该错误是由于发送的证书已被回车字符序列破坏所致。这是它的样子:

  <wsse:BinarySecurityToken
    EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
    ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
    wsu:Id="X509-124b3a03-73e3-4838-a254-f20883ff4184">MIIG1zCCBb+gAwIBAgIRAIVi4APh2tBtAAAAAFDvSXwwDQYJKoZIhvcNAQELBQAwgboxCzAJBgNV&#13;
    BAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu&#13; bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1&#13; dGhvcml6ZWQgdXNlIG9ubHkxLjAsBgNVBAMTJUVudHJ1c3QgQ2VydGlmaWNhdGlvbiBBdXRob3Jp&#13;
    dHkgLSBMMUswHhcNMTkwMzIyMTY1ODA5WhcNMjAwMzIyMTcyODA4WjCBgjELMAkGA1UEBhMCVVMx&#13; EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCEJlcmtlbGV5MS4wLAYDVQQKEyVMYXdyZW5j&#13; ZSBCZXJrZWxleSBOYXRpb25hbCBMYWJvcmF0b3J5MRswGQYDVQQDExJtc2cudWNwLWl0LmxibC5n&#13;
    b3YwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9fSfO1cKz1D34dQaQF1ScY0eEGALm&#13; s3hkRRWMYPWTH8gZRpfP4iFLF9Sx09vagGFHUrru1xf8BnVyB2CsZnvHtE+bDrK4kp4hQpO8aXqf&#13; VEpn+SpY38aQDfZUqjRK6HJM5qxF/2xjNKSw41MPkXALK04yga07IwSUE+GpPt8i2noQPKKJufzf&#13;
    guA8Plmsnf9uNcpxFezNXC1k+HQBKeO0V+CZ4K5FKyckq64eT8VWbawF5CFoNigtbxTuHHClECV0&#13; VrzNNf5jj/cpymwOu51ljnPhGEY/f73DlEBZg8jpFcDSnAyYyJH2GFgz2wa0TiOpdxItTWHMXalb&#13; YtDH9VvRAgMBAAGjggMMMIIDCDAdBgNVHREEFjAUghJtc2cudWNwLWl0LmxibC5nb3YwggF/Bgor&#13;
    BgEEAdZ5AgQCBIIBbwSCAWsBaQB2AFWB1MIWkDYBSuoLm1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAAB&#13; aaZyHvYAAAQDAEcwRQIhAJtC0LBFOfupRDy6BOvRrH6pAlvAJFFUWxMbbSRV59nOAiB/c2D5VOwS&#13; aBeC4czjDjUAAfeunN/npVLyX7i6v69aLgB3AId1v+dZfPiMQ5lfvfNu/1aNR1Y2/0q1YMG06v9e&#13;
    oIMPAAABaaZyHwQAAAQDAEgwRgIhAJj/g/g+UjWaoHCl7ldHG08zuUrL8XbAkR8Op4G+//nvAiEA&#13; sLoq29TrwnOtWa+O1+PRHCCllKD22yeKxdMUNrR2Pu0AdgCyHgXMi6LNiiBOh2b5K7mKJSBna9r6&#13; cOeySVMt74uQXgAAAWmmch7YAAAEAwBHMEUCIBVGxbR2c/ByOtfDRMlpIFPRYA5+dGkB4zJ7tjQ6&#13;
    moYYAiEAmFbeJdg9rCZt6qUqhRH2mxJlotRjp+mZmiHyRFmulykwDgYDVR0PAQH/BAQDAgWgMB0G&#13; A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js&#13; LmVudHJ1c3QubmV0L2xldmVsMWsuY3JsMEsGA1UdIAREMEIwNgYKYIZIAYb6bAoBBTAoMCYGCCsG&#13;
    AQUFBwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L3JwYTAIBgZngQwBAgIwaAYIKwYBBQUHAQEE&#13; XDBaMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAzBggrBgEFBQcwAoYnaHR0&#13; cDovL2FpYS5lbnRydXN0Lm5ldC9sMWstY2hhaW4yNTYuY2VyMB8GA1UdIwQYMBaAFIKicHTdvFM/&#13;
    z3vU981/p2DGCky/MB0GA1UdDgQWBBRzakStBRG3O6NBdLt1XUkvwwKn4jAJBgNVHRMEAjAAMA0G&#13; CSqGSIb3DQEBCwUAA4IBAQAqt00w3oV4XgcdhcanJdgY/SUCtmN9I4jdras8vRson+wK6WJy6Em8&#13; EF5wyRDLOwUD75Rm9Ak23lKjYOcDTWQGG3YXrYh7xe3J8C+plEY1NAwNPXflCzxkDcdJ4pX0LDfj&#13;
    aC5FniAvKJ9ET7ZQvpCjBRd7wgOrkuhf3YjCFC3hM4E6D7cGb6DEhCh9nOy+e9woQ/C1LnDil3NX&#13; Vgqk3PMZYkUeHjxqItnDcOAeJaeqsAUiTxZbC8sQQ9ae/CPahghgSWEwL7tMrAH4nGT3yeBQl0I9&#13; O7H9xWj0ooQ8Wt6nO7pq64X5uc7W6iA3/1Of5uCntmMrsqPlvSscP6QVuPw6</wsse:BinarySecurityToken>

我的密钥库是 PKCS 格式,我也已转换为 jks。没有骰子。密钥库中的证书使用 openssl 命令验证得很好,所以我知道它们很好。

我在 Mac 上构建并部署在 CentOS 上。我还将源代码复制到 CentOS 并在那里运行构建。再次,没有区别。

有没有人遇到过这个问题并解决了?将不胜感激任何帮助!

非常感谢!

标签: spring-bootspring-wsws-securitywss4j

解决方案


xmlsec 库升级到 2.1.3。wss4j-ws-security-dom 升级到 2.2.3

细节:这个问题很狭窄而且非常模糊。我还没有把我所做的一切都恢复到原来的样子,看看问题是否会再次出现,但我可以很容易地做到这一点。我们使用来自 apache 的 spring-ws-security 和 WSS4J 来执行验证和安全操作。这两个库都包含提供此功能的 xmlsec.jar。事实上 wss4j 包含它两次,因为它还嵌入了 opensaml ,而后者又包含 xmlsec。Spring-ws-security 还包含自己的 xmlsec。它们都是不同的版本。xmlsec 2.1.0 及更高版本报告了回车问题。

https://issues.apache.org/jira/browse/SANTUARIO-482

https://issues.apache.org/jira/browse/SANTUARIO-494

我将 wss4j 更新到了 2.2.3 版(表面上这是固定的),并且还直接添加了 xmlsec.jar 的固定版本,以便更好地衡量。

希望它可以帮助别人。:-)


推荐阅读