JBoss.org Community Documentation

8.6.1. Providing Password Information for SRP

The default implementation of the SRPVerifierStore interface is not likely to be suitable for your production security environment as it requires all password hash information to be available as a file of serialized objects. You need to provide an MBean service that provides an implementation of the SRPVerifierStore interface that integrates with your existing security information stores. The SRPVerifierStore interface is shown in.

package org.jboss.security.srp;

import java.io.IOException;
import java.io.Serializable;
import java.security.KeyException;

public interface SRPVerifierStore
{
    public static class VerifierInfo implements Serializable
    {
        /**
         * The username the information applies to. Perhaps redundant
         * but it makes the object self contained.
         */
        public String username;

        /** The SRP password verifier hash */
        public byte[] verifier;
        /** The random password salt originally used to verify the password */
        public byte[] salt;
        /** The SRP algorithm primitive generator */
        public byte[] g;
        /** The algorithm safe-prime modulus */
        public byte[] N;
    }
    
    /**
     *  Get the indicated user's password verifier information.
     */
    public VerifierInfo getUserVerifier(String username)
        throws KeyException, IOException;
    /** 
     *  Set the indicated users' password verifier information. This
     *  is equivalent to changing a user's password and should
     *  generally invalidate any existing SRP sessions and caches.
     */
    public void setUserVerifier(String username, VerifierInfo info)
        throws IOException;

    /** 
     * Verify an optional auxiliary challenge sent from the client to
     * the server.  The auxChallenge object will have been decrypted
     * if it was sent encrypted from the client. An example of a
     * auxiliary challenge would be the validation of a hardware token
     * (SafeWord, SecureID, iButton) that the server validates to
     * further strengthen the SRP password exchange.
     */
     public void verifyUserChallenge(String username, Object auxChallenge)
         throws SecurityException;
} 

The primary function of a SRPVerifierStore implementation is to provide access to the SRPVerifierStore.VerifierInfo object for a given username. The getUserVerifier(String) method is called by the SRPService at that start of a user SRP session to obtain the parameters needed by the SRP algorithm. The elements of the VerifierInfo objects are:

  • username : The user's name or id used to login.

  • verifier : This is the one-way hash of the password or PIN the user enters as proof of their identity. The org.jboss.security.Util class has a calculateVerifier method that performs that password hashing algorithm. The output password H(salt | H(username | ':' | password)) as defined by RFC2945. Here H is the SHA secure hash function. The username is converted from a string to a byte[] using the UTF-8 encoding.

  • salt : This is a random number used to increase the difficulty of a brute force dictionary attack on the verifier password database in the event that the database is compromised. It is a value that should be generated from a cryptographically strong random number algorithm when the user's existing clear-text password is hashed.

  • g : The SRP algorithm primitive generator. In general this can be a well known fixed parameter rather than a per-user setting. The org.jboss.security.srp.SRPConf utility class provides several settings for g including a good default which can obtained via SRPConf.getDefaultParams().g().

  • N : The SRP algorithm safe-prime modulus. In general this can be a well known fixed parameter rather than a per-user setting. The org.jboss.security.srp.SRPConf utility class provides several settings for N including a good default which can obtained via SRPConf.getDefaultParams().N().

So, step 1 of integrating your existing password store is the creation of a hashed version of the password information. If your passwords are already store in an irreversible hashed form, then this can only be done on a per-user basis as part of an upgrade procedure for example. Note that the setUserVerifier(String, VerifierInfo) method is not used by the current SRPSerivce and may be implemented as no-op method, or even one that throws an exception stating that the store is read-only.

Step 2 is the creation of the custom SRPVerifierStore interface implementation that knows how to obtain the VerifierInfo from the store you created in step 1. The verifyUserChallenge(String, Object) method of the interface is only called if the client SRPLoginModule configuration specifies the hasAuxChallenge option. This can be used to integrate existing hardware token based schemes like SafeWord or Radius into the SRP algorithm.

Step 3 is the creation of an MBean that makes the step 2 implementation of the SRPVerifierStore interface available via JNDI, and exposes any configurable parameters you need. In addition to the default org.jboss.security.srp.SRPVerifierStoreService example, the SRP example presented later in this chapter provides a Java properties file based SRPVerifierStore implementation. Between the two examples you should have enough to integrate your security store.

Example 8.10. The SRPVerifierStore interface