Save This Page
Home » crypto-143 » org.bouncycastle.crypto.agreement.srp » [javadoc | source]
    1   package org.bouncycastle.crypto.agreement.srp;
    2   
    3   import java.math.BigInteger;
    4   import java.security.SecureRandom;
    5   
    6   import org.bouncycastle.crypto.CryptoException;
    7   import org.bouncycastle.crypto.Digest;
    8   
    9   /**
   10    * Implements the client side SRP-6a protocol. Note that this class is stateful, and therefore NOT threadsafe.
   11    * This implementation of SRP is based on the optimized message sequence put forth by Thomas Wu in the paper
   12    * "SRP-6: Improvements and Refinements to the Secure Remote Password Protocol, 2002"
   13    */
   14   public class SRP6Client
   15   {
   16       protected BigInteger N;
   17       protected BigInteger g;
   18   
   19       protected BigInteger a;
   20       protected BigInteger A;
   21   
   22       protected BigInteger B;
   23   
   24       protected BigInteger x;
   25       protected BigInteger u;
   26       protected BigInteger S;
   27   
   28       protected Digest digest;
   29       protected SecureRandom random;
   30   
   31       public SRP6Client()
   32       {
   33       }
   34   
   35       /**
   36        * Initialises the client to begin new authentication attempt
   37        * @param N The safe prime associated with the client's verifier
   38        * @param g The group parameter associated with the client's verifier
   39        * @param digest The digest algorithm associated with the client's verifier
   40        * @param random For key generation
   41        */
   42       public void init(BigInteger N, BigInteger g, Digest digest, SecureRandom random)
   43       {
   44           this.N = N;
   45           this.g = g;
   46           this.digest = digest;
   47           this.random = random;
   48       }
   49   
   50       /**
   51        * Generates client's credentials given the client's salt, identity and password
   52        * @param salt The salt used in the client's verifier.
   53        * @param identity The user's identity (eg. username)
   54        * @param password The user's password
   55        * @return Client's public value to send to server
   56        */
   57       public BigInteger generateClientCredentials(byte[] salt, byte[] identity, byte[] password)
   58       {
   59           this.x = SRP6Util.calculateX(digest, N, salt, identity, password);
   60           this.a = selectPrivateValue();
   61           this.A = g.modPow(a, N);
   62   
   63           return A;
   64       }
   65   
   66       /**
   67        * Generates client's verification message given the server's credentials
   68        * @param serverB The server's credentials
   69        * @return Client's verification message for the server
   70        * @throws CryptoException If server's credentials are invalid
   71        */
   72       public BigInteger calculateSecret(BigInteger serverB) throws CryptoException
   73       {
   74           this.B = SRP6Util.validatePublicValue(N, serverB);
   75           this.u = SRP6Util.calculateU(digest, N, A, B);
   76           this.S = calculateS();
   77   
   78           return S;
   79       }
   80   
   81       protected BigInteger selectPrivateValue()
   82       {
   83       	return SRP6Util.generatePrivateValue(digest, N, g, random);    	
   84       }
   85   
   86       private BigInteger calculateS()
   87       {
   88           BigInteger k = SRP6Util.calculateK(digest, N, g);
   89           BigInteger exp = u.multiply(x).mod(N).add(a).mod(N);
   90           BigInteger tmp = g.modPow(x, N).multiply(k).mod(N);
   91           return B.subtract(tmp).mod(N).modPow(exp, N);
   92       }
   93   }

Save This Page
Home » crypto-143 » org.bouncycastle.crypto.agreement.srp » [javadoc | source]