1

I am trying to test a Guidewire application that uses Cognito for user portal Login authentication. A Javascript is downloaded, at the application launch, that is generating SRP_A string

There are a few solutions mentioned on Stack Exchange and Stack Overflow but we could appreciate if you could give more detailed steps to generate this string

2
  • Did you got solution ? If yes, can you share more details on its implementation in JMeter. Thanks.
    – Ashwani
    Commented Aug 11, 2021 at 11:09
  • What is HKDF here?And what are the dependencies to be added?
    – Sravani
    Commented Oct 9, 2023 at 9:27

1 Answer 1

1

You can generate this SRP_A value using suitable JSR223 Test Element and Groovy language.

Here is example code you can use as it is or as a reference:

import com.amazonaws.AmazonClientException
import com.amazonaws.util.StringUtils

import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.security.SecureRandom

/**
 *
 * @author marcus
 */
public class AuthenticationHelper {

    private BigInteger a;
    private BigInteger A;
    private String poolName;

    public AuthenticationHelper(String userPoolName) {
        do {
            a = new BigInteger(EPHEMERAL_KEY_LENGTH, SECURE_RANDOM).mod(N);
            A = GG.modPow(a, N);
        } while (A.mod(N).equals(BigInteger.ZERO));

        if (userPoolName.contains("_")) {
            poolName = userPoolName.split("_", 2)[1];
        } else {
            poolName = userPoolName;
        }
    }

    public BigInteger geta() {
        return a;
    }

    public BigInteger getA() {
        return A;
    }

    private static final String HEX_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
    + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
    + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
    + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
    + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
    + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
    + "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
    + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
    + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
    + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
    + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
    + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
    + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
    + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
    + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
    + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
    private static final BigInteger N = new BigInteger(HEX_N, 16);
    private static final BigInteger GG = BigInteger.valueOf(2);
    private static final BigInteger KK;

    private static final int EPHEMERAL_KEY_LENGTH = 1024;
    private static final int DERIVED_KEY_SIZE = 16;
    private static final String DERIVED_KEY_INFO = "Caldera Derived Key";

    private static final ThreadLocal<MessageDigest> THREAD_MESSAGE_DIGEST = new ThreadLocal<MessageDigest>() {
        @Override
        protected MessageDigest initialValue() {
            try {
                return MessageDigest.getInstance("SHA-256");
            } catch (final NoSuchAlgorithmException e) {
                throw new AmazonClientException("Exception in authentication", e);
            }
        }
    };

    private static final SecureRandom SECURE_RANDOM;

    static {
        try {
            SECURE_RANDOM = SecureRandom.getInstance("SHA1PRNG");

            final MessageDigest messageDigest = THREAD_MESSAGE_DIGEST.get();
            messageDigest.reset();
            messageDigest.update(N.toByteArray());
            final byte[] digest = messageDigest.digest(GG.toByteArray());
            KK = new BigInteger(1, digest);
        } catch (final NoSuchAlgorithmException e) {
            throw new AmazonClientException(e.getMessage(), e);
        }
    }

    public byte[] getPasswordAuthenticationKey(String userId,
                                               String userPassword,
                                               BigInteger B,
                                               BigInteger salt) {
        // Authenticate the password
        // u = H(A, B)
        final MessageDigest messageDigest = THREAD_MESSAGE_DIGEST.get();
        messageDigest.reset();
        messageDigest.update(A.toByteArray());
        final BigInteger u = new BigInteger(1, messageDigest.digest(B.toByteArray()));
        if (u.equals(BigInteger.ZERO)) {
            throw new AmazonClientException("Hash of A and B cannot be zero");
        }

        // x = H(salt | H(poolName | userId | ":" | password))
        messageDigest.reset();
        messageDigest.update(poolName.getBytes(StringUtils.UTF8));
        messageDigest.update(userId.getBytes(StringUtils.UTF8));
        messageDigest.update(":".getBytes(StringUtils.UTF8));
        final byte[] userIdHash = messageDigest.digest(userPassword.getBytes(StringUtils.UTF8));

        messageDigest.reset();
        messageDigest.update(salt.toByteArray());
        final BigInteger x = new BigInteger(1, messageDigest.digest(userIdHash));
        final BigInteger s = (B.subtract(KK.multiply(GG.modPow(x, N)))
                .modPow(a.add(u.multiply(x)), N)).mod(N);

        Hkdf hkdf = null;
        try {
            hkdf = Hkdf.getInstance("HmacSHA256");
        } catch (final NoSuchAlgorithmException e) {
            throw new AmazonClientException(e.getMessage(), e);
        }
        hkdf.init(s.toByteArray(), u.toByteArray());
        final byte[] key = hkdf.deriveKey(DERIVED_KEY_INFO, DERIVED_KEY_SIZE);
        return key;
    }

}

More information:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.