}
public String executeStep2(String password, String serverFirstMessage) throws NoSuchAlgorithmException
{
MessageDigest md = MessageDigest.getInstance("SHA-1");
MacBasedPRF hmac = new MacBasedPRF("HMacSha1");
StringTokenizer st = new StringTokenizer(serverFirstMessage, "=", true);
st.nextToken("=");
st.nextToken();
String serverR = st.nextToken(",");
st.nextToken();
st.nextToken("=");
st.nextToken();
byte[] serverSalt = Base64Coder.decodeLines(st.nextToken(","));
st.nextToken();
st.nextToken("=");
st.nextToken();
String iterationCount = st.nextToken(",");
// SaltedPassword := Hi(Normalize(password), salt, i)
PBKDF2Engine engine = new PBKDF2Engine(new PBKDF2Parameters("HMacSHA1", null, serverSalt, Integer.parseInt(iterationCount)));
byte[] saltedPassword = engine.deriveKey(password, 20);
// ClientKey := HMAC(SaltedPassword, "Client Key")
hmac.init(saltedPassword);
byte[] clientKey = hmac.doFinal("Client Key".getBytes());
// StoredKey := H(ClientKey)
byte[] storedKey = md.digest(clientKey);
// AuthMessage := client-first-message-bare + "," +
// server-first-message + "," +
// client-final-message-without-proof
String clientFinalMessage = "c=biws,r=" + serverR;
String strAuthMessage = clientFirstMessageBare + "," + serverFirstMessage + "," + clientFinalMessage;
// ClientSignature := HMAC(StoredKey, AuthMessage)
hmac = new MacBasedPRF("HMacSha1");
hmac.init(storedKey);
byte[] clientSignature = hmac.doFinal(strAuthMessage.getBytes());
// ClientProof := ClientKey XOR ClientSignature
for (int i = 0; i < 20; i++)
{
clientKey[i] ^= clientSignature[i];