The SRP protocol is an implementation of a public key exchange handshake described in the Internet Standards Working Group RFC 2945. The RFC 2945 abstract states the following:
Note You can obtain the complete RFC 2945 specification from www.rfc-editor.org/rfc.html. Additional information on the SRP algorithm and its history can be found at http://srp.stanford.edu/. SRP is similar in concept and security to other public key exchange algorithms, such as Diffie-Hellman and RSA. SRP is based on simple string passwords in a way that does not require a clear-text password to exist on the server. This is in contrast to other public keybased algorithms that require client certificates and the corresponding certificate management infrastructure. Algorithms such as Diffie-Hellman and RSA are known as public key exchange algorithms. The concept of public key algorithms is that there are two keys: one that is public and is available to everyone and one that is private and known only to you. When someone wants to send encrypted information to you, that person encrypts the information using your public key. Only you are able to decrypt the information using your private key. This contrasts with the more traditional shared passwordbased encryption schemes that require the sender and receiver to know the shared password. Public key algorithms eliminate the need to share passwords. The JBossSX framework includes an implementation of SRP that consists of the following elements:
Figure 8.14 shows a diagram of the key components involved in the JBossSX implementation of the SRP client/server framework. Figure 8.14. The JBossSX components of the SRP client/server framework.On the client side, SRP shows up as a custom JAAS LoginModule implementation that communicates to the authentication server through an org.jboss.security.srp.SRPServerInterface proxy. A client enables authentication using SRP by creating a login configuration entry that includes the org.jboss.security.srp.jaas.SRPLoginModule. This module supports the following configuration options:
Any other options that are passed in and do not match one of the previously named options is treated as a JNDI property to use for the environment passed to the InitialContext constructor. This is useful if the SRP server interface is not available from the default InitialContext. The SRPLoginModule needs to be configured along with the standard ClientLoginModule to allow the SRP authentication credentials to be used for validation of access to security J2EE components. The following is an example of a login configuration entry that demonstrates such a setup: srp { org.jboss.security.srp.jaas.SRPLoginModule required srpServerJndiName="SRPServerInterface" ; org.jboss.security.ClientLoginModule required password-stacking="useFirstPass" ; }; On the JBoss server side, two MBeans manage the objects that collectively make up the SRP server: org.jboss.security.srp.SRPService and org.jboss.security.srpSRPVerifierStoreService. The primary service is the org.jboss.security.srp.SRPService MBean, and it is responsible for exposing an RMI-accessible version of the SRPServerInterface as well as updating the SRP authentication session cache. The configurable SRPService MBean attributes include the following:
The one input setting is the VerifierSourceJndiName attribute. This is the location of the SRP password information store implementation that must be provided and made available through JNDI. The org.jboss.security.srpSRPVerifierStoreService is an example of an MBean service that binds an implementation of the SRPVerifierStore interface that uses a file of serialized objects as the persistent store. Although this MBean is not realistic for a production environment, it does allow for testing of the SRP protocol and provides an example of the requirements for an SRPVerifierStore service. The configurable SRPVerifierStoreService MBean attributes include the following:
The SRPVerifierStoreService MBean also supports addUser and delUser operations for addition and deletion of users. These are the signatures: public void addUser(String username, String password) throws IOException; public void delUser(String username) \ throws IOException; Providing Password Information for SRPThe default implementation of the SRPVerifierStore interface is not likely to be suitable for your production security environment because 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 Listing 8.12. Listing 8.12. The SRPVerifierStore Interfacepackage 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 an * 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 SRPVerifier-Store.VerifierInfo object for a given username. SRPService calls the getUserVerifier(String) method at that start of a user SRP session to obtain the parameters needed by the SRP algorithm. The elements of the VerifierInfo objects are as follows:
These are the steps in integrating your existing password store:
Inside the SRP AlgorithmThe appeal of the SRP algorithm is that is allows for mutual authentication of the client and server, using simple text passwords without a secure communication channel. You might be wondering how this is done. If you want the complete details and theory behind the algorithm, refer to http://srp.stanford.edu. Six steps are performed to complete authentication:
Although SRP has many interesting properties, it is still an evolving component in the JBossSX framework and has some limitations of which you should be aware. Issues of note include the following:
To use end-to-end SRP authentication for J2EE component calls, you need to configure the security domain under which the components are secured to use the org.jboss.security.srp.jaas.SRPCacheLoginModule. The SRPCacheLoginModule has a single configuration option named cacheJndiName that sets the JNDI location of the SRP authentication CachePolicy instance. This must correspond to the AuthenticationCacheJndiName attribute value of the SRPService MBean. The SRPCacheLoginModule authenticates user credentials by obtaining the client challenge from the SRPServerSession object in the authentication cache and comparing this to the challenge passed as the user credentials. Figure 8.15 illustrates the operation of the SRPCacheLoginModule.login method implementation. Figure 8.15. A sequence diagram that illustrates the interaction of the SRPCacheLoginModule with the SRP session cache.An SRP ExampleThis chapter has covered quite a bit of material on SRP, and now it is time to demonstrate SRP in practice with an example. This example demonstrates client-side authentication of the user via SRP as well as subsequent secured access to a simple EJB, using the SRP session challenge as the user credential. The test code deploys an EJB JAR that includes a SAR for the configuration of the server-side login module configuration and SRP services. As in the previous examples, in this example you will dynamically install the server-side login module configuration by using the SecurityConfig MBean. This example also uses a custom implementation of the SRPVerifierStore interface that uses an in-memory store that is seeded from a Java properties file rather than a serialized object store, as used by the SRPVerifierStoreService. This custom service is org.jboss.chap8.ex3.service.PropertiesVerifierStore. The following shows the contents of the JAR that contains the sample EJB and SRP services: [examples]$ java -cp output/classes ListJar output/chap8/chap8-ex3.jar output/chap8/chap8-ex3.jar +- META-INF/MANIFEST.MF +- META-INF/ejb-jar.xml +- META-INF/jboss.xml +- org/jboss/chap8/ex3/Echo.class +- org/jboss/chap8/ex3/EchoBean.class +- org/jboss/chap8/ex3/EchoHome.class +- roles.properties +- users.properties +- chap8-ex3.sar (archive) | +- META-INF/MANIFEST.MF | +- META-INF/jboss-service.xml | +- META-INF/login-config.xml | +- org/jboss/chap8/ex3/service/PropertiesVerifierStore$1.class | +- org/jboss/chap8/ex3/service/PropertiesVerifierStore.class | +- org/jboss/chap8/ex3/service/PropertiesVerifierStoreMBean.class | +- org/jboss/chap8/service/SecurityConfig.class | +- org/jboss/chap8/service/SecurityConfigMBean.class The key SRP-related items in this example are the SRP MBean services configuration and the SRP login module configurations. The jboss-service.xml descriptor of chap8-ex3.sar is shown in Listing 8.13, and Listing 8.14 and Listing 8.15 show the sample client-side and server-side login module configurations. Listing 8.13. The chap8-ex3.sar jboss-service.xml Descriptor for the SRP Services<server> <!-- The custom JAAS login configuration that installs a Configuration capable of dynamically updating the config settings --> <mbean code="org.jboss.chap8.service.SecurityConfig" name="jboss.docs.chap8:service=LoginConfig-EX3"> <attribute name="AuthConfig">META-INF/login-config.xml</attribute> <attribute name="SecurityConfigName">jboss.security:name=SecurityConfig</attribute> </mbean> <!-- The SRP service that provides the SRP RMI server and server side authentication cache --> <mbean code="org.jboss.security.srp.SRPService" name="jboss.docs.chap8:service=SRPService"> <attribute name="VerifierSourceJndiName">srp-test/chap8-ex3</attribute> <attribute name="JndiName">srp-test/SRPServerInterface</attribute> <attribute name="AuthenticationCacheJndiName">srp-test/AuthenticationCache</attribute> <attribute name="ServerPort">0</attribute> <depends>jboss.docs.chap8:service=PropertiesVerifierStore</depends> </mbean> <!-- The SRP store handler service that provides the user password verifier information --> <mbean code="org.jboss.chap8.ex3.service.PropertiesVerifierStore" name="jboss.docs.chap8:service=PropertiesVerifierStore"> <attribute name="JndiName">srp-test/chap8-ex3</attribute> </mbean> </server> Listing 8.14. The Client-Side Standard JAAS Configurationsrp { org.jboss.security.srp.jaas.SRPLoginModule required srpServerJndiName="srp-test/SRPServerInterface" ; org.jboss.security.ClientLoginModule required password-stacking="useFirstPass" ; }; Listing 8.15. The Server-Side XMLLoginConfig Configuration<application-policy name="chap8-ex3"> <authentication> <login-module code="org.jboss.security.srp.jaas.SRPCacheLoginModule" flag = "required"> <module-option name="cacheJndiName">srp-test/AuthenticationCache</module-option> </login-module> <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag = "required"> <module-option name="password-stacking">useFirstPass</module-option> </login-module> </authentication> </application-policy> The sample services are ServiceConfig and the PropertiesVerifierStore and SRPService MBeans. Note that the JndiName attribute of PropertiesVerifierStore is equal to the VerifierSourceJndiName attribute of SRPService and that SRPService depends on PropertiesVerifierStore. This is required because SRPService needs an implementation of the SRPVerifierStore interface for accessing user password verification information. The client-side login module configuration makes use of SRPLoginModule with a srpServerJndiName option value that corresponds to the JBoss server component SRPService JndiName attribute value (srptest/SRPServerInterface). Also needed is ClientLoginModule, configured with the password-stacking="useFirstPass" value to propagate the user authentication credentials generated by the SRPLoginModule to the EJB invocation layer. There are two issues to note about the server-side login module configuration. First, note that the cacheJndiName=srp-test/AuthenticationCache configuration option tells SRPCacheLoginModule the location of the CachePolicy that contains the SRPServerSession for users who have authenticated against the SRPService. This value corresponds to the SRPService AuthenticationCacheJndiName attribute value. Second, the configuration includes a UsersRolesLoginModule with the password-stacking=useFirstPass configuration option. You need to use a second login module with the SRPCacheLoginModule because SRP is only an authentication technology. You need to configure a second login module that accepts the authentication credentials validated by the SRPCacheLoginModule to set the principal's roles to determine the principal's permissions. The UsersRolesLoginModule augments the SRP authentication with properties filebased authorization. The user's roles are coming from the roles.properties file included in the EJB JAR. Now, you can run the client by executing the following command from the book examples directory: [examples]$ ant -Dchap=chap8 -Dex=3 run-example ... run-example3: [copy] Copying 1 file to /tmp/jboss-4.0.1/server/default/deploy [echo] Waiting for 5 seconds for deploy... [java] Logging in using the 'srp' configuration [java] Created Echo [java] Echo.echo()#1 = This is call 1 [java] Echo.echo()#2 = This is call 2 In the examples/logs directory is a file called ex3-trace.log. This is a detailed trace of the client side of the SRP algorithm. Such traces show step-by-step the construction of the public keys, challenges, session key, and verification. Note that the client in this example takes a long time to run relative to the other simple examples. The reason for this is the construction of the client's public key, which involves the creation of a cryptographically strong random number; this process takes quite a bit of time the first time it occurs. If you were to log out and log in again within the same VM, the process would be much faster. Also note that Echo.echo()#2 fails with an authentication exception. The client code sleeps for 15 seconds after making the first call to demonstrate the behavior of the SRPService cache expiration. The SRPService cache policy timeout is set to a mere 10 seconds to force this issue. As stated earlier, you need to make the cache timeout very long or handle re-authentication on failure. |