- edited description
SRP6VerifierGenerator generates verifier arrays of incorrect length
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)
-
reporter -
i have created a branch
issue23
with the code that demos it that you had put on branchiss22
. -
- marked as minor
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.
-
@Jase Bleazard You should use
BigIntegerUtils#bigIntegerToBytes
instead ofbigInteger.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. - Log in to comment