001package com.bitbucket.thinbus.srp6.js; 002 003import com.nimbusds.srp6.XRoutine; 004 005import java.math.BigInteger; 006import java.security.MessageDigest; 007 008import static com.nimbusds.srp6.BigIntegerUtils.fromHex; 009import static com.nimbusds.srp6.BigIntegerUtils.toHex; 010 011public class HexHashedXRoutine implements XRoutine { 012 013 final BigInteger N; 014 015 public HexHashedXRoutine(BigInteger N){ 016 this.N = N; 017 } 018 019 /** 020 * Computes the password key 'x'. 021 * 022 * @param digest 023 * The hash function 'H'. 024 * @param salt 025 * The salt 's'. This is considered a mandatory argument in 026 * computation of 'x'. Must not be {@code null} or empty. 027 * @param username 028 * The user identity 'I'. Must not be {@code null} or empty. 029 * @param password 030 * The user password 'P'. This is considered a mandatory argument 031 * in the computation of 'x'. Must not be {@code null} or empty. 032 * 033 * @return The resulting 'x' value. 034 */ 035 @Override 036 public BigInteger computeX(MessageDigest digest, byte[] salt, 037 byte[] username, byte[] password) { 038 final String i = new String(username, HexHashedRoutines.utf8); 039 final String p = new String(password, HexHashedRoutines.utf8); 040 final String s = toHex(new BigInteger(1, salt)); 041 042 if (i == null || i.trim().isEmpty()) 043 throw new IllegalArgumentException( 044 "The user identity 'I' must not be null or empty"); 045 046 if (p == null || p.trim().isEmpty()) 047 throw new IllegalArgumentException( 048 "The user password 'P' must not be null or empty"); 049 050 if (s == null || s.trim().isEmpty()) 051 throw new IllegalArgumentException( 052 "The user salt 's' must not be null or empty"); 053 054 final String hash = HexHashedRoutines.hashCredentials(digest, s, i, p); 055 final BigInteger X = fromHex(hash).mod(N); 056 return X; 057 } 058 059}