SRP6VerifierGenerator generates verifier arrays of incorrect length

Issue #23 new
Jase Bleazard created an issue

Verification arrays are required to be a certain size. However, with certain salts, the arrays are 1 byte too long with any bit-size parameter. As an example:

SRP6CryptoParams params = SRP6CryptoParams.getInstance(2048, "SHA-512");
SRP6VerifierGenerator generator = new SRP6VerifierGenerator(params);
BigInteger salt = BigIntegerUtils.fromHex("0ab328f77affefa10385c941a1042440");
BigInteger vKey = generator.generateVerifier(salt.toByteArray(), "".getBytes(), "password".getBytes());

assertEquals(16, generator.generateRandomSalt(16).length);
assertEquals(256, vKey.toByteArray().length);

This will assert on the last line because the array length is 257 instead of 256.

Comments (4)

  1. simon

    Hi Jase

    The verifier is computed using the standard java.math.BigInteger library:

    connect2id/nimbus-srp/src/bf978679534541bbb53744a4e95226206f74a4ec/src/main/java/com/nimbusds/srp6/SRP6Routines.java#lines-122

    so what I think is happening is that at random the fist bytes will be 0. Then when the number is converted into hex string it isnt being packed with leading zero characters ‘0’.

    This wont effect the security which is based on the math not the string encoding of the numbers sent on the wire. What it might effect is someone who defines the database column that stores the verifier to be a fix width of characters. They can probably left pad the strong with zeros.

    If I am correct it should be harmless to left pad in nimbus. This should be the case as the hex decode to big decimal will ignore the leading bytes. There has to be a test for that to ensure that it is safe to make this minor change.

  2. Jonathan Haas

    @Jase Bleazard You should use BigIntegerUtils#bigIntegerToBytes instead of bigInteger.toByteArray() for your conversion. The reason is that the first bit in the byte array of the Java implementation represents the sign bit, so if the first bit would be set, Java adds an empty 0 byte at the beginning to keep the number positive. BigIntegerUtils#bigIntegerToBytes works around that.

  3. Log in to comment