This discussion is archived
2 Replies Latest reply: Aug 13, 2010 7:38 AM by 843810 RSS

Unable to sign SOAP Kerberos Token Profile message

843810 Newbie
Currently Being Moderated
I'm constructing a SOAP Kerberos Token Profile message in Java 1.6 and am unable to sign the BinarySecurityToken to send to a .NET service.

My aim is to achieve SSO from the Windows Desktop for the user that has already logged on using a Java Client.
(i.e. I don't want to use JAAS to ask the user to login again).

Based on my reading so far, I'm using the javax.security.auth.useSubjectCredsOnly set to false to force the use of the underlying mechanism (in this case the windows credential cache).

I've also configured the jaas.conf as follows:

com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required debug=true useTicketCache=true doNotPrompt=true;
};

My problem is this, in order to sign the BinarySecurityToken element, which contains the Base64 encoded Kerberos service ticket, I need to gain access to the shared session key which is embedded in the service ticket.

Some other posts, in particular this (excellently written) one,
http://thejavamonkey.blogspot.com/2008/05/hacking-jvm-kerberos-libraries-session.html

demonstrate how to do this, by this assumes the use of a JAAS subject and takes advantage of the feature that the GSS-API copies the session key to the private credentials of the Subject when initiating a security context.

However I cannot use storekey=true in combination with the above configuration, as the excerpt from the Krb5LoginModule states:

storeKey=true useTicketCache = true doNotPrompt=true;;

This is an illegal combination since storeKey is set to true but the key can not be obtained either by prompting the user or from the keytab.A configuratin error will occur.

I note that when I step through the code, the session key does indeed seem to be available on the gssCredential object as a property:

gssCredential->tempCred->sessionKey->keyBytes[16]

which seems to be the expected session key size 16 * 8 = 128 (Basic128)

However I cannot find any GSS API method that can obtain this key! I note another reference from the Oracle API:
http://download.oracle.com/docs/cd/E15523_01/apirefs.1111/e10678/oracle/security/xmlsec/wss/kerberos/package-summary.html

In particular this handy method:
<ul><li>Sign/Encrypt using the kerberos session key
     There is no public API to get the session key, so we have provided a utility method.
     SecretKey sessionKey = KerberosUtils.getSessionKey(gssContext);
     WSSEncryptionParams eParams = new WSSEncryptionParams(XMLURI.alg_tripleDES_CBC, sessionKey, null, null, str);
     WSSecurity.encryptNoEncKey(...)
</li>
</ul>
This looks like exactly what I'm after however this API seems related to Oracle 11g so I'm not sure if it is:
- open source
- if this is the intended usage by the GSS API developers?

Any help on this point would be very greatly appreciated!

Edited by: jas71 on Aug 4, 2010 8:49 AM
  • 1. Re: Unable to sign SOAP Kerberos Token Profile message
    843810 Newbie
    Currently Being Moderated
    Well a little more searching through the javadocs gave me the answer:

    Subject subject = GSSUtil.getSubject(gssName, gssCredential);

    Now it's a matter of using javamonkey's code (again great post) to obtain the session key:

    http://thejavamonkey.blogspot.com/2008/05/hacking-jvm-kerberos-libraries-session.html

    Now all that's left is the use this key to create the signature and attach it to the SOAP header...
  • 2. Re: Unable to sign SOAP Kerberos Token Profile message
    843810 Newbie
    Currently Being Moderated
    Validation of the signature on the .NET server is failing with the following error:

    *The key size requirements for the 'Basic128' algorithm suite are not met by the
    'System.IdentityModel.Tokens.KerberosReceiverSecurityToken' token which has key
    size of '64'*

    I'm using the session key to create the signature value as follows:

    private static String generateSignatureValue(byte[] sessionKey, String cipherText) {

    final String mode = "HmacSHA1";
    final SecretKey key = new SecretKeySpec(sessionKey, mode);
    Mac mac;
    try {
    mac = Mac.getInstance(mode);
    mac.init(key);
    byte[] signatureValueBytes = mac.doFinal(cipherText.getBytes());
    return new String(Base64.encodeBase64(signatureValueBytes));

    The error is surprising given that the session key used in this method is actually 16 bytes long and would appear to meet the key size requirements (16 * 8 = 128 bit)?

    This appears to be the last piece in the puzzle, signing the Kerberos Token Profile SOAP request.