Policy for signing and encrypting

3.2k Views Asked by At

I need to implement a jax-ws client.

Here is what the provider docs say about security

Currently, we use the SOAP Message Security version 1.0 specification at http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf

This standard uses two other from W3C norm:
XMLENC (http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/)
and XMLDSIG (http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/)

For the signature, a “SecurityTokenReference” using a direct “reference” specifying “URI” and “valueType” of X509 is mandatory. For the enciphering, we recommend it too, but also we support in order of preference a reference to a keyIdentifier, a X509IssuerSerial or a keyName.

The enciphered and signed block has to be the “body” tag.

We recommend to use: “rsa-sha1” for signature, “rsa-1_5” for encrypting key and “tripledes-cbc” for encrypting body.

So I came up with following policy (generated from netbeans). But... it doens't look right to me. The web service isn't reachable yet, but I'm not sure that the spec versions match. I read a lot on the subject, but I'm still somewhat confused. Does this policy look ok?

<wsp1:Policy wsu:Id="ListeOperationsPeriodeSoapBindingSoapPolicy">
    <wsp1:ExactlyOne>
        <wsp1:All>
            <sp:TransportBinding>
                <wsp1:Policy>
                    <sp:TransportToken>
                        <wsp1:Policy>
                            <sp:HttpsToken RequireClientCertificate="false"/>
                        </wsp1:Policy>
                    </sp:TransportToken>
                    <sp:Layout>
                        <wsp1:Policy>
                            <sp:Lax/>
                        </wsp1:Policy>
                    </sp:Layout>
                    <sp:AlgorithmSuite>
                        <wsp1:Policy>
                            <sp:TripleDesRsa15/>
                        </wsp1:Policy>
                    </sp:AlgorithmSuite>
                </wsp1:Policy>
            </sp:TransportBinding>
            <sp:Wss10/>
            <sp:EndorsingSupportingTokens>
                <wsp1:Policy>
                    <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                        <wsp1:Policy>
                            <sp:WssX509V3Token10/>
                        </wsp1:Policy>
                    </sp:X509Token>
                </wsp1:Policy>
            </sp:EndorsingSupportingTokens>

        </wsp1:All>
    </wsp1:ExactlyOne>
</wsp1:Policy>
<wsp:Policy wsu:Id="ListeOperationsPeriodeSoapBindingSoap_perform_Input_Policy">
    <wsp:ExactlyOne>
        <wsp:All>
            <sp1:SignedEncryptedSupportingTokens>
                <wsp:Policy>
                    <sp1:X509Token sp1:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                        <wsp:Policy>
                            <sp1:WssX509V3Token10/>
                        </wsp:Policy>
                    </sp1:X509Token>
                </wsp:Policy>
            </sp1:SignedEncryptedSupportingTokens>
        </wsp:All>
    </wsp:ExactlyOne>

</wsp:Policy>

EDIT: I couldn't get it to send the expected message with wsit-yet. As an example, using Netbeans wizard, I couldn't get an encrypted header without using addressing. Is it supposed to be possible?

I hacked something with an old axis 1 class and wss4j, it works but it's ugly and I'd rather use something more future-proof.

2

There are 2 best solutions below

3
On

Maybe you want to try with CXF instead of WSIT? http://cxf.apache.org/docs/ws-security.html

3
On

You seem confused indeed. In general you should have a single policy. In your case, you risk accepting unsecured web service calls because you have one policy defining transport binding (https), while the other is not.

Also, since you have a transport binding, that means the entire body will be encrypted by the transport protocol (https). You don't need to specify body encryption explicitly. In fact, this binding will encrypt everything except the http header.

The transport binding really is the easiest way to get secure web services. If you want total control, you have to write your own symmetric or asymetric binding depending on your needs. Asymetric is more complex because it requires a certificate on both sides, while asymetric requires only a server certificate (accepts anonymous clients). Asymetric and symmetric bindings require care. They are designed to be highly flexible and will let you design any policy, even if vulnerable to certain attacks.

When not using transport binding, then you must specify the body must be encrypted. As stated in the specs:

sp:EncryptedParts/sp:Body

Or translated into xml:

<sp:EncryptedParts>
  <sp:Body/>
</sp:EncryptedParts>

Similarly, if you want the body to be signed:

<sp:SignedParts>
  <sp:Body/>
</sp:SignedParts>

There are more options to specify signature/encryption order, whether to encrypt the signature or not, etc.

As the name implies, policies such as sp:EndorsingSupportingToken apply to supporting tokens. The type I'm familiar with is the username token you can include inside web services requests.

The WS-SecurityPolicy specification is the single most useful doc I have read to understand policies. You should take time to read this thoroughly. It details things quite well and contains useful examples. It is good to read different versions of the docs since some aspects will be better documented in more recent versions. Note I linked v1.3.

Setup a web service client and server and write simple tests. Especially if you are new to web services.

One tool that will help you formulate policies quickly is SoapUI. It did not support exactly what I needed but it helped me learn a couple of things. It has a great UI and it is not very hard to use.

Get some examples or build some, then deconstruct them with the help of the specification.

I have found policies to be quite complex. Be prepared to absorb a lot of concepts!