Class SRP6Routines

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

public class SRP6Routines
extends java.lang.Object
implements java.io.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:
Serialized Form
  • Constructor Summary

    Constructors
    Constructor Description
    SRP6Routines()  
  • Method Summary

    Modifier and Type Method Description
    java.math.BigInteger computeClientEvidence​(java.security.MessageDigest digest, java.math.BigInteger A, java.math.BigInteger B, java.math.BigInteger S)
    Computes the client evidence message M1 = H(A | B | S)
    java.math.BigInteger computeK​(java.security.MessageDigest digest, java.math.BigInteger N, java.math.BigInteger g)
    Computes the SRP-6 multiplier k = H(N | PAD(g))
    java.math.BigInteger computePublicClientValue​(java.math.BigInteger N, java.math.BigInteger g, java.math.BigInteger a)
    Computes the public client value A = g^a (mod N)
    java.math.BigInteger computePublicServerValue​(java.math.BigInteger N, java.math.BigInteger g, java.math.BigInteger k, java.math.BigInteger v, java.math.BigInteger b)
    Computes the public server value B = k * v + g^b (mod N)
    protected java.math.BigInteger computeServerEvidence​(java.security.MessageDigest digest, java.math.BigInteger A, java.math.BigInteger M1, java.math.BigInteger S)
    Computes the server evidence message M2 = H(A | M1 | S)
    java.math.BigInteger computeSessionKey​(java.math.BigInteger N, java.math.BigInteger v, java.math.BigInteger u, java.math.BigInteger A, java.math.BigInteger b)
    Computes the session key S = (A * v^u) ^ b (mod N) from server-side parameters.
    java.math.BigInteger computeSessionKey​(java.math.BigInteger N, java.math.BigInteger g, java.math.BigInteger k, java.math.BigInteger x, java.math.BigInteger u, java.math.BigInteger a, java.math.BigInteger B)
    Computes the session key S = (B - k * g^x) ^ (a + u * x) (mod N) from client-side parameters.
    java.math.BigInteger computeU​(java.security.MessageDigest digest, java.math.BigInteger N, java.math.BigInteger A, java.math.BigInteger B)
    Computes the random scrambling parameter u = H(PAD(A) | PAD(B))
    java.math.BigInteger computeVerifier​(java.math.BigInteger N, java.math.BigInteger g, java.math.BigInteger x)
    Computes a verifier v = g^x (mod N)
    java.math.BigInteger computeX​(java.security.MessageDigest digest, byte[] salt, byte[] password)
    Computes x = H(s | H(P))
    java.math.BigInteger generatePrivateValue​(java.math.BigInteger N, java.security.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.
    static byte[] generateRandomSalt​(int numBytes)
    Generates a random salt 's'.
    static byte[] generateRandomSalt​(int numBytes, java.security.SecureRandom random)
    Generates a random salt 's'.
    protected byte[] getPadded​(java.math.BigInteger n, int length)
    Pads a big integer with leading zeros up to the specified length.
    protected java.math.BigInteger hashPaddedPair​(java.security.MessageDigest digest, java.math.BigInteger N, java.math.BigInteger n1, java.math.BigInteger n2)
    Hashes two padded values 'n1' and 'n2' where the total length is determined by the size of N.
    boolean isValidPublicValue​(java.math.BigInteger N, java.math.BigInteger value)
    Validates an SRP6 client or server public value ('A' or 'B').

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • SRP6Routines

      public SRP6Routines()
  • Method Details

    • computeK

      public java.math.BigInteger computeK​(java.security.MessageDigest digest, java.math.BigInteger N, java.math.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, java.security.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 java.math.BigInteger computeX​(java.security.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 java.math.BigInteger computeVerifier​(java.math.BigInteger N, java.math.BigInteger g, java.math.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 java.math.BigInteger generatePrivateValue​(java.math.BigInteger N, java.security.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 java.math.BigInteger computePublicClientValue​(java.math.BigInteger N, java.math.BigInteger g, java.math.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 java.math.BigInteger computePublicServerValue​(java.math.BigInteger N, java.math.BigInteger g, java.math.BigInteger k, java.math.BigInteger v, java.math.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​(java.math.BigInteger N, java.math.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 java.math.BigInteger computeU​(java.security.MessageDigest digest, java.math.BigInteger N, java.math.BigInteger A, java.math.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 java.math.BigInteger computeSessionKey​(java.math.BigInteger N, java.math.BigInteger g, java.math.BigInteger k, java.math.BigInteger x, java.math.BigInteger u, java.math.BigInteger a, java.math.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 java.math.BigInteger computeSessionKey​(java.math.BigInteger N, java.math.BigInteger v, java.math.BigInteger u, java.math.BigInteger A, java.math.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 java.math.BigInteger computeClientEvidence​(java.security.MessageDigest digest, java.math.BigInteger A, java.math.BigInteger B, java.math.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 java.math.BigInteger computeServerEvidence​(java.security.MessageDigest digest, java.math.BigInteger A, java.math.BigInteger M1, java.math.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 java.math.BigInteger hashPaddedPair​(java.security.MessageDigest digest, java.math.BigInteger N, java.math.BigInteger n1, java.math.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​(java.math.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.