jchambers / java-otp

A one-time password (HOTP/TOTP) library for Java
MIT License
455 stars 122 forks source link

When first digit of generated pin is 0, it is being handled as octal number #16

Closed kougianos closed 4 years ago

kougianos commented 4 years ago

As the title says, there are some times when the first digit of the randomly generated One Time Pin is 0. In those cases, Java handles the integer as octal, and the generateOneTimePassword method returns the decimal value of the octal number generated.

For example, if generateOneTimePassword generates 012345 (6 digits), it will return the integer 5349 (4 digits), which is the decimal representation of the octal 012345.

Related issues: https://github.com/jchambers/java-otp/issues/14 https://github.com/jchambers/java-otp/issues/4

Workaround, as stated in issue #14 :

String oneTimePasswordString = String.format("%06d", oneTimePassword);
jchambers commented 4 years ago

I'm sorry—I'm not quite following. generateOneTimePassword returns an int, which has no notion of the base in which it's represented. Can you provide a test case that demonstrates the problem?

kougianos commented 4 years ago

Thanks for the prompt reply. I don't have a specific test case, I just assumed this behaviour after noticing that the generated pin consists of 5 digits (when TimeBasedOneTimePasswordGenerator was constructed with the default passwordLength=6 ) and reading https://stackoverflow.com/questions/35521278/what-does-an-integer-that-has-zero-in-front-of-it-mean-and-how-can-i-print-it

Just FYI, after generating 100 pins that were supposed to be 6 digits, 13 of them had 5 digits. Some of them, like 23698 equal with a 6-digit octal number that starts with 0 (056222) but some others don't.

TL;DR My initial guess was that if the generated pin is 23698, then the algorithm actually produced int 056222 and then Java automatically converted 056222 to 23698, but that doesn't seem to be the case.

Nevertheless, I have a strict requirement that my service should always generate 6-digit pins, so I will manually add leading zeroes if a 5-digit pin is created.

I would appreciate an explanation to this, but feel free to close this issue without digging more into it.

jchambers commented 4 years ago

This is not a bug, and is explained in detail in https://github.com/jchambers/java-otp/issues/14#issuecomment-657075722.

There is no octal conversion happening. Looking ahead, if you're trying to parse strings into integers for verification, I'd recommend specifying a radix to avoid unwanted octal conversion:

final int code = Integer.parse(codeString, 10);