Class SRP6Routines

java.lang.Object
de.bsvrz.sys.funclib.srp6.SRP6Routines
All Implemented Interfaces:
Serializable

public class SRP6Routines extends Object implements Serializable
Secure Remote Password (SRP-6a) routines for computing the various protocol variables and messages.

The routines comply with RFC 5054 (SRP for TLS), with the following exceptions:

  • The computation of the password key 'x' is modified to omit the user identity 'I' in order to allow for server-side user identity renaming as well as authentication with multiple alternate identities.
  • The evidence messages 'M1' and 'M2' are computed according to Tom Wu's paper "SRP-6: Improvements and refinements to the Secure Remote Password protocol", table 5, from 2002.

This class contains portions of code from Bouncy Castle's SRP6 implementation.

See Also:
  • Constructor Details

    • SRP6Routines

      public SRP6Routines()
  • Method Details

    • computeK

      public BigInteger computeK(MessageDigest digest, BigInteger N, BigInteger g)
      Computes the SRP-6 multiplier k = H(N | PAD(g))

      Specification: RFC 5054.

      Parameters:
      digest - The hash function 'H'. Must not be null.
      N - The prime parameter 'N'. Must not be null.
      g - The generator parameter 'g'. Must not be null.
      Returns:
      The resulting multiplier 'k'.
    • generateRandomSalt

      public static byte[] generateRandomSalt(int numBytes)
      Generates a random salt 's'.
      Parameters:
      numBytes - The number of bytes the salt 's' must have.
      Returns:
      The salt 's' as a byte array.
    • generateRandomSalt

      public static byte[] generateRandomSalt(int numBytes, SecureRandom random)
      Generates a random salt 's'.
      Parameters:
      numBytes - The number of bytes the salt 's' must have.
      random - A secure random number generator
      Returns:
      The salt 's' as a byte array.
    • computeX

      public BigInteger computeX(MessageDigest digest, byte[] salt, byte[] password)
      Computes x = H(s | H(P))

      Note that this method differs from the RFC 5054 recommendation which includes the user identity 'I', i.e. x = H(s | H(I | ":" | P))

      Parameters:
      digest - The hash function 'H'. Must not be null.
      salt - The salt 's'. Must not be null.
      password - The user password 'P'. Must not be null.
      Returns:
      The resulting 'x' value.
    • computeVerifier

      public BigInteger computeVerifier(BigInteger N, BigInteger g, BigInteger x)
      Computes a verifier v = g^x (mod N)

      Specification: RFC 5054.

      Parameters:
      N - The prime parameter 'N'. Must not be null.
      g - The generator parameter 'g'. Must not be null.
      x - The password key 'x', see computeX(java.security.MessageDigest, byte[], byte[]). Must not be null.
      Returns:
      The resulting verifier 'v'.
    • generatePrivateValue

      public BigInteger generatePrivateValue(BigInteger N, SecureRandom random)
      Generates a random SRP-6a client or server private value ('a' or 'b') which is in the range [1,N-1] generated by a random number of at least 256 bits.

      Specification: RFC 5054.

      Parameters:
      N - The prime parameter 'N'. Must not be null.
      random - Source of randomness. Must not be null.
      Returns:
      The resulting client or server private value ('a' or 'b').
    • computePublicClientValue

      public BigInteger computePublicClientValue(BigInteger N, BigInteger g, BigInteger a)
      Computes the public client value A = g^a (mod N)

      Specification: RFC 5054.

      Parameters:
      N - The prime parameter 'N'. Must not be null.
      g - The generator parameter 'g'. Must not be null.
      a - The private client value 'a'. Must not be null.
      Returns:
      The public client value 'A'.
    • computePublicServerValue

      public BigInteger computePublicServerValue(BigInteger N, BigInteger g, BigInteger k, BigInteger v, BigInteger b)
      Computes the public server value B = k * v + g^b (mod N)

      Specification: RFC 5054.

      Parameters:
      N - The prime parameter 'N'. Must not be null.
      g - The generator parameter 'g'. Must not be null.
      k - The SRP-6a multiplier 'k'. Must not be null.
      v - The password verifier 'v'. Must not be null.
      b - The private server value 'b'. Must not be null.
      Returns:
      The public server value 'B'.
    • isValidPublicValue

      public boolean isValidPublicValue(BigInteger N, BigInteger value)
      Validates an SRP6 client or server public value ('A' or 'B').

      Specification: RFC 5054.

      Parameters:
      N - The prime parameter 'N'. Must not be null.
      value - The public value ('A' or 'B') to validate.
      Returns:
      true on successful validation, else false.
    • computeU

      public BigInteger computeU(MessageDigest digest, BigInteger N, BigInteger A, BigInteger B)
      Computes the random scrambling parameter u = H(PAD(A) | PAD(B))

      Specification: RFC 5054.

      Parameters:
      digest - The hash function 'H'. Must not be null.
      N - The prime parameter 'N'. Must not be null.
      A - The public client value 'A'. Must not be null.
      B - The public server value 'B'. Must not be null.
      Returns:
      The resulting 'u' value.
    • computeSessionKey

      public BigInteger computeSessionKey(BigInteger N, BigInteger g, BigInteger k, BigInteger x, BigInteger u, BigInteger a, BigInteger B)
      Computes the session key S = (B - k * g^x) ^ (a + u * x) (mod N) from client-side parameters.

      Specification: RFC 5054

      Parameters:
      N - The prime parameter 'N'. Must not be null.
      g - The generator parameter 'g'. Must not be null.
      k - The SRP-6a multiplier 'k'. Must not be null.
      x - The 'x' value, see computeX(java.security.MessageDigest, byte[], byte[]). Must not be null.
      u - The random scrambling parameter 'u'. Must not be null.
      a - The private client value 'a'. Must not be null.
      B - The public server value 'B'. Must note be null.
      Returns:
      The resulting session key 'S'.
    • computeSessionKey

      public BigInteger computeSessionKey(BigInteger N, BigInteger v, BigInteger u, BigInteger A, BigInteger b)
      Computes the session key S = (A * v^u) ^ b (mod N) from server-side parameters.

      Specification: RFC 5054

      Parameters:
      N - The prime parameter 'N'. Must not be null.
      v - The password verifier 'v'. Must not be null.
      u - The random scrambling parameter 'u'. Must not be null.
      A - The public client value 'A'. Must not be null.
      b - The private server value 'b'. Must not be null.
      Returns:
      The resulting session key 'S'.
    • computeClientEvidence

      public BigInteger computeClientEvidence(MessageDigest digest, BigInteger A, BigInteger B, BigInteger S)
      Computes the client evidence message M1 = H(A | B | S)

      Specification: Tom Wu's paper "SRP-6: Improvements and refinements to the Secure Remote Password protocol", table 5, from 2002.

      Parameters:
      digest - The hash function 'H'. Must not be null.
      A - The public client value 'A'. Must not be null.
      B - The public server value 'B'. Must note be null.
      S - The session key 'S'. Must not be null.
      Returns:
      The resulting client evidence message 'M1'.
    • computeServerEvidence

      protected BigInteger computeServerEvidence(MessageDigest digest, BigInteger A, BigInteger M1, BigInteger S)
      Computes the server evidence message M2 = H(A | M1 | S)

      Specification: Tom Wu's paper "SRP-6: Improvements and refinements to the Secure Remote Password protocol", table 5, from 2002.

      Parameters:
      digest - The hash function 'H'. Must not be null.
      A - The public client value 'A'. Must not be null.
      M1 - The client evidence message 'M1'. Must not be null.
      S - The session key 'S'. Must not be null.
      Returns:
      The resulting server evidence message 'M2'.
    • hashPaddedPair

      protected BigInteger hashPaddedPair(MessageDigest digest, BigInteger N, BigInteger n1, BigInteger n2)
      Hashes two padded values 'n1' and 'n2' where the total length is determined by the size of N.

      H(PAD(n1) | PAD(n2))

      Parameters:
      digest - The hash function 'H'. Must not be null.
      N - Its size determines the pad length. Must not be null.
      n1 - The first value to pad and hash.
      n2 - The second value to pad and hash.
      Returns:
      The resulting hashed padded pair.
    • getPadded

      protected byte[] getPadded(BigInteger n, int length)
      Pads a big integer with leading zeros up to the specified length.
      Parameters:
      n - The big integer to pad. Must not be null.
      length - The required length of the padded big integer as a byte array.
      Returns:
      The padded big integer as a byte array.