daegalus / dart-otp

RFC6238 Time-Based One-Time Password / Google Authenticator Library
MIT License
100 stars 25 forks source link

does not match the result of GoogleAuthenticator #17

Closed cyjaysong closed 4 years ago

cyjaysong commented 4 years ago

Hello, I don't know if it's used correctly. I tried generate TOTPCodeString using the plugin, but it does not match the result of GoogleAuthenticator

daegalus commented 4 years ago

Ok, I will probably need a little more information to help/diagnose.

Is the secret Base32 encoded? Is the time the same? Are you using the same Algorithm?

You can also just provide me the info you are passing into both places so I can try to reproduce.

cyjaysong commented 4 years ago
import 'package:otp/otp.dart';

void main() async {
  String secret = "DDXFM42476476545";
  int milliseconds = DateTime.now().millisecondsSinceEpoch;
  String _codeStr = OTP.generateTOTPCodeString(secret, milliseconds,
      algorithm: Algorithm.SHA1);
  print(_codeStr);
}
daegalus commented 4 years ago

Well the first thing is Google Authenticator uses SHA256 for it's algorithm. Try that first.

cyjaysong commented 4 years ago

However, I modified the following method, which will match with Google Authenticator

  static int _generateCode(
      String secret, int time, int length, Hash mac, int secretbytes,
      {bool isHOTP = false}) {
    length = (length > 0) ? length : 6;

    var secretList = base32.decode(secret);

    if (!isHOTP || useTOTPPaddingForHOTP) {
//      secretList = _padSecret(secretList, secretbytes);
    } else {
      _showHOTPWarning(mac);
    }
daegalus commented 4 years ago

I was told that Google Authenticator had moved to SHA256 and it's why I didn't include and edge case for it.

Padding apparently needs to be off for Google Authenticator if your change works.

daegalus commented 4 years ago

I added a new isGoogle optional boolean for TOTP codes. I think that should fix it for you. It is in the 2.2.0 release.

OTP.generateTOTPCodeString(secret, milliseconds, algorithm: Algorithm.SHA1, isGoogle: true);

cyjaysong commented 4 years ago

OK nice!

chickahoona commented 3 years ago

Just for reference for others that might find this problem. In order to create the same codes as the regular google authenticator one has to use this:

OTP.generateTOTPCodeString(
        "JBSWY3DPEHPK3PXP",
        DateTime.now().millisecondsSinceEpoch,
        algorithm: Algorithm.SHA1,
        isGoogle: true,
)

I compared the output to the latest available Google authenticator on Android (5.10) and iOS (3.3.1) and dart-otp version 2.2.3.