- WSHandlerConstants.SIG_KEY_ID ("signatureKeyIdentifier").
- WSHandlerConstants.ENC_KEY_ID ("encryptionKeyIdentifier").
When creating a Signature you have the option of adding content to the Signature KeyInfo Element. This lets the recipient know what certificate/public key to use to verify the signature. Specifying a value for WSHandlerConstants.SIG_KEY_ID allows you to change how to refer to the key.
When encrypting some part of the message, a session key is typically generated and used to encrypt the message part, which is then wrapped in an EncryptedData Element. This refers (typically via a Direct Reference) to a EncryptedKey Element in the security header, where the session key is encrypted using the public key of the recipient. Specifying a value for WSHandlerConstants.ENC_KEY_ID allows you to change how to refer to the public key of the recipient in the EncryptedKey KeyInfo element.
The following valid values for these configuration items are:
- IssuerSerial (default)
- DirectReference
- X509KeyIdentifier
- Thumbprint
- SKIKeyIdentifier
- KeyValue (signature only)
- EncryptedKeySHA1 (encryption only)
This (default) key identifier method means that the Issuer Name and Serial Number of a X.509 Certificate is included directly in the KeyInfo Element. For example:
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>CN=XYZ</ds:X509IssuerName>
<ds:X509SerialNumber>124124....</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
The certificate is not included in the message and so the recipient will have to have access to the certificate matching the given Issuer Name and Serial Number in a keystore.
2) DirectReference
This key identifier method is used when the X.509 Certificate is included in the message, unlike the IssuerSerial case above. The certificate is Base-64 encoded and included in the request via a BinarySecurityToken element, e.g.:
<wsse:BinarySecurityToken EncodingType="...#Base64Binary"
ValueType="...#X509v3">MIIBY...
</wsse:BinarySecurityToken>
This Certificate is then referred to directly from the KeyInfo Element as follows:
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#X509-..." ValueType="...#X509v3"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
3) X509KeyIdentifier
This key identifier method is similar to DirectReference, in that the certificate is included in the request. However, instead of referring to a certificate, the certificate is included directly in the KeyInfo element, e.g.:
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="...#Base64Binary"
ValueType="...#X509v3">MIIB...
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
4) Thumbprint
This Key Identifier method refers to the Certificate via a SHA-1 Thumbprint. The certificate may or may not be included in the request. For example:
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="...#Base64Binary"
ValueType="...#ThumbprintSHA1">
5epW9GhL6s0kC9X9egsRZ90ooeE=
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
5) SKIKeyIdentifier
This Key Identifier method refers to a Certificate via a Base-64 encoding of the Subject Key Identifier, e.g.:
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="...#Base64Binary"
ValueType="...#X509SubjectKeyIdentifier">
2DUoN4ppxJz/RNgcCDsJ4SocPdk=
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
6) KeyValue
This Key Identifier method only applies for Signatures. It includes the (RSA) PublicKey directly in the Signature KeyInfo Element as follows:
<ds:KeyInfo>
<ds:KeyValue>
<ds:RSAKeyValue>
<ds:Modulus>tfJ29N0G1...</ds:Modulus>
<ds:Exponent>AQAB</ds:Exponent>
</ds:RSAKeyValue>
</ds:KeyValue>
</ds:KeyInfo>
7) EncryptedKeySHA1
This Key Identifier method only applies for Encryption. Unlike the previous methods it refers to the way the EncryptedData references the EncryptedKey Element, rather than the way the EncryptedKey Element refers to the public key. For example:
<ds:KeyInfo>
<wsse:KeyIdentifier EncodingType="...#Base64Binary"
ValueType="...#EncryptedKeySHA1">
X/8wvCY...
</wsse:KeyIdentifier>
</ds:KeyInfo>
Thanks for this, very useful! Is there a way using WSS4J to produce the following structure via configuration?
ReplyDelete<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>...
<SignatureValue>...
<KeyInfo>
<X509Data>
<X509SubjectName>CN=EIL2-CHUQ...
<X509Certificate>MIIFG...
</X509Data>
</KeyInfo>
</Signature>
</Security>
I realize that sticking the X509Data right in the KeyInfo goes against the OASIS recommendation to use BinarySecurityToken to pass key material, but I'm trying to follow a spec that requires this. Any idea?
Thanks!
There is currently no way to support this. I guess what we need is a pluggable CallbackHandler type approach to allow users to specify custom KeyInfos. Is this something you'd be interested in contributing to WSS4J?
ReplyDeleteColm.
I looked over the source code a bit yesterday and it doesn't look easy. There's a getSignatureKeyId method which returns an int from all these different things (which reminds me, there's also an "EmbeddedKeyName" that you don't have listed here which seems to apply only to encryption). So seems like it would need some "custom" value added to the list, and that list seems to get checked in a few places- meaning it would need to touch a variety of places to make it work.
DeleteThen in the case of that custom value, I guess it would have to read another field which would be your CallbackHandler. I'm not sure at this point what all stuff it would have to pass to that handler to be able to accommodate the various scenarios people might dream up. This is the point where my understanding is lacking in order to be able to do this.
Also, this appears to be a one-off and the first I've personally seen of this nature where some consultant felt that following existing standards wouldn't be appropriate. So I'm not sure the effort would be usable for more than my particular case.
Ok, that sounds reasonable. I guess you can always swap out the SignatureAction in WSS4J with your own implementation if required.
ReplyDeleteColm.
Hi Colm,
ReplyDeleteWhat assertion should we put to a WS-SecurityPolicy document in order to require the option 2, DirectReference. I have seen there are possibilities like MustSupportRefKeyIdentifier, MustSupportRefIssuerSerial, MustSupportRefExternalURI, MustSupportRefEmbeddedToken. The last one would make sense for me. But in general, how do these security policy assertions correlate to the key reference options you mention in the article?
This comment has been removed by the author.
ReplyDeleteI don't think there is a specific way of requiring Direct Reference via policy as such. You have the following policy options:
Deletesp:RequireKeyIdentifierReference
sp:RequireIssuerSerialReference
sp:RequireEmbeddedTokenReference
sp:RequireThumbprintReference .
This comment has been removed by the author.
ReplyDeleteThank you, Colm, that's very useful info.
ReplyDeleteCan WSS4J be set to omit KeyInfo field at all?
No, apparently not. Want to submit a patch...?
DeleteThis comment has been removed by the author.
ReplyDeleteI need to Sign (no Timestamp, no Encryption) a Web Service Envelope so that the "ds:KeyInfo" section of the signed XML includes a "ds:X509Certificate" as shown below. I know this is not recomended, but I'm forced to do it.
ReplyDelete[ds:KeyInfo]
[wsse:SecurityTokenReference]
[ds:X509Data]
[ds:X509IssuerSerial]
[ds:X509IssuerName]C=CL,...,CN=Name[/ds:X509IssuerName]
[ds:X509SerialNumber]162...970[/ds:X509SerialNumber]
[/ds:X509IssuerSerial]
[ds:X509Certificate]MIA1g...ljnELi+[/ds:X509Certificate]
[/ds:X509Data]
[/wsse:SecurityTokenReference]
[/ds:KeyInfo]
Please, how can I do this using lastest version of Apache WSS4J (2.1.7)?
Hello Eduardo,
DeleteIt's been 2 weeks that I try to find a solution to this, but always in vain.
Please, help me.
Thanks.
You can create the SecurityTokenReference Element yourself and then inject it into WSSecSignature directly using the "setSecurityTokenReference" method. Example here: ("testCustomSTR") https://svn.apache.org/repos/asf/webservices/wss4j/branches/2_1_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/SignatureTest.java
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHello Team,
ReplyDeleteI would like to contact you about a problemI have during 2 week on WS-SECURITY using CXF 3.1.3 (jax-ws).
Indeed, my configuration file spring like this :
[entry key="action" value="Signature" /]
[entry key="signaturePropFile" value="security.out.properties"/]
[entry key="user" value="${user}"/]
[entry key="passwordCallbackRef"]
[ref bean="serverPasswordCallback"/]
[/entry]
[entry key="signatureKeyIdentifier" value="X509KeyIdentifier"/]
[entry key="signatureDigestAlgorithm" value="http://www.w3.org/2001/04/xmlenc#sha256"/]
[entry key="signatureAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/]
[entry key="signatureParts" value="{Content}{}Body "/]
[entry key="schema-validation-enabled" value="false" /]
[entry key="security.sts.token.usecert" value="true" /]
By specifying key "signatureKeyIdentifier" as "X509KeyIdentifier" value, I got a result at the section "keyInfo" as follows:
[ds: KeyInfo]
[wsse: SecurityTokenReference]
[wsse: KeyIdentifier EncodingType = "... # Base64Binary"
ValueType = "# ... X509v3"] MIIB ...
[/ wsse: KeyIdentifier]
[/ wsse: SecurityTokenReference]
[/ ds: KeyInfo]
By cons, this is not the result I want, I want a result like this:
[ds: KeyInfo Id = "KI-ED321E02A6CAE33F8615378788884713"]
[ds: X509Data]
[X509Certificate] MIICXTCCA .. [/ X509Certificate]
[/ds: X509Data]
[/ds: KeyInfo]
It's been 2 weeks that I try to find a solution to this, but always in vain.
Thank you for your help.
Cordially,
Hello, I have the same problem. Did you find the solution?
DeleteI've replied to your mail on the CXF users list, please send any follow up there.
ReplyDelete