0

我在使用 CXF WS-Security 和签名验证时遇到了问题。我WSS4JInInterceptor在服务器端使用以验证Body元素上的签名。
- 当我使用 e BinarySecurityToken( DirectReference) 作为关键标识符类型时,一切正常;
- 当我使用X509IssuerSerial( IssuerSerial) 作为服务器端的密钥标识符类型签名验证失败。
这是服务器端的配置:

<bean id="wss4jIn" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
    <constructor-arg>
        <map>
            <entry key="action" value="Signature" />
            <entry key="signaturePropFile" value="config/security/truststore.properties" />
            <entry key="signatureAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
            <entry key="signatureKeyIdentifier" value="X509IssuerSerial"/>
            <entry key="signatureParts"
                value="{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body" />
        </map>
    </constructor-arg>
</bean>

如果我(从客户端)发送带有此 SOAPHeader 的 SOAPEnvelope:

<SOAP-ENV:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" SOAP-ENV:mustUnderstand="1">
        <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-69c28b5e-3566-4fab-b26f-bd28e97c21e9">
            <ds:SignedInfo>
                <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                    <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="SOAP-ENV enc xsd xsi"/>
                </ds:CanonicalizationMethod>
                <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                <ds:Reference URI="#_e078e477-59bc-401d-83f5-a11925947d19">
                    <ds:Transforms>
                        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                            <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="enc xsd xsi"/>
                        </ds:Transform>
                    </ds:Transforms>
                    <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                    <ds:DigestValue>MMQ1CZWFv5ZK3KMzEpWyBVpFas73hXiedDeKyKjRUQ4=</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>Amn7favWhD9RA6SHrJ6RYf6BIhdRH2N2r3WXh2+auBi3MlPstcBFA1oqBrVt3PPvTs/LZrrt6AfZWspp0YpjPEdTuDuEd1x8HrSKBgxBt+QUqfiio4WGhUJ4k/5b/loNd9D1a48ic0PloM3FsNHf+kQJeb5rPeW5f8aeRtFBUCg=</ds:SignatureValue>
            <ds:KeyInfo Id="KI-b49617ba-b2d8-4bad-9c46-d772389537df">
                <wsse:SecurityTokenReference wsu:Id="STR-4e662377-c736-48c5-a0c1-11a1473769ee">
                    <ds:X509Data>
                        <ds:X509IssuerSerial>
                            <ds:X509IssuerName>1.2.840.113549.1.9.1=#xxx,CN=xxx,OU=xxx,O=xxx,L=xxx,ST=xx,C=xx</ds:X509IssuerName>
                            <ds:X509SerialNumber>xxx</ds:X509SerialNumber>
                        </ds:X509IssuerSerial>
                    </ds:X509Data>
                </wsse:SecurityTokenReference>
            </ds:KeyInfo>
        </ds:Signature>
    </wsse:Security>
</SOAP-ENV:Header>

我会得到 SOAPFault:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <soap:Fault>
        <faultcode xmlns:ns1="http://ws.apache.org/wss4j">ns1:SecurityError</faultcode>
        <faultstring>A security error was encountered when verifying the message</faultstring>
    </soap:Fault>
</soap:Body>

使用调试日志输出,我没有得到太多信息。但是在调试时,我发现org.apache.wss4j.dom.processor.SignatureProcessor此时失败了:

 if ((certs == null || certs.length == 0 || certs[0] == null) 
        && secretKey == null
        && publicKey == null) {
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
    }

在 wss4j-ws-security-dom-2.1.0 中引发异常的是第 197 行。这意味着 certificate 和 publicKey 为空。这使我得出一个结论,即我从一开始就想得不够——我没有意识到没有可以验证签名的证书。另外,我的结论是,在 X509IssuerSerial 的情况下,只有在接收端(在这种情况下为服务器)端有证书的情况下,您才能验证签名。
有没有人有更好的解释?

4

0 回答 0