java - HOTP 不会生成与 Google 身份 validator 相同的代码

标签 java one-time-password google-authenticator

目前,我正在为 Android 的 Java HOTP 实现而苦苦挣扎。我正在尝试生成 OTP 代码,将它们与登录应用程序的用户输入进行匹配。为此,我使用这个 script 。 当我创建一些从移动因子 0 到 19 的测试值时,我得到以下代码:

106764
867240
658913
270241
373368
105291
051234
812749
615640
648397
846312
825014
565042
820956
757355
372673
964093
451446
360409

这些代码都是从 Base32 编码的共享 key 生成的:AECQIBADA3PK3PXP

当我将这些代码与 Google Authenticator 应用生成的代码进行比较时,它们总是不同的。 Google 身份 validator 应用中没有任何代码与上述代码之一匹配。

我使用以下 URI 生成了 QR 码,所以我不知道我做错了什么:

otpauth://hotp/Hash%20based?secret=AECQIBADA3PK3PXP&issuer=Testserver&counter=0&algorithm=SHA1

有人可以帮助我吗?提前致谢。

最佳答案

我将此代码与您的 secret 一起使用,生成的 OTP 与 Google 身份 validator 相同。

使用 0<=counter<=100 调用此方法。您将会看到结果。

public static final int[] DIGITS_POWER
        //  0  1   2     3    4        5        6       7         8
        = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};

public String generateHOTP(long count, String seedString) {

    byte[] counter = new byte[8];
    long movingFactor = count;

    for (int i = counter.length - 1; i >= 0; i--) {
        counter[i] = (byte) (movingFactor & 0xff);
        movingFactor >>= 8;
    }

    //from org.apache.commons.codec.binary.Base32;

    Base32 base32 = new Base32();
    byte[] seed = base32.decode(seedString);


    byte[] hash = HMAC(seed, counter);
    int offset = hash[hash.length - 1] & 0xf;

    int otpBinary = ((hash[offset] & 0x7f) << 24)
            | ((hash[offset + 1] & 0xff) << 16)
            | ((hash[offset + 2] & 0xff) << 8)
            | (hash[offset + 3] & 0xff);

    int otp = otpBinary % DIGITS_POWER[6];
    String result = Integer.toString(otp);

    while (result.length() < 6) {
        result = "0" + result;
    }
    return result;

}

 private byte[] HMAC(byte[] seed, byte[] counter) {

    try {
        Mac hmac = Mac.getInstance("HmacSHA1");
        SecretKeySpec macKey = new SecretKeySpec(seed, "RAW");
        hmac.init(macKey);
        return hmac.doFinal(counter);

    } catch (GeneralSecurityException ex) {
        throw new UndeclaredThrowableException(ex);
    }
}

关于java - HOTP 不会生成与 Google 身份 validator 相同的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51758349/

相关文章:

java - 使用 "Move Selection"快捷方式取消选择树上的某些内容时无法知道取消选择的项目

java - 为什么我在 java 中使用 httpClient 的 post 方法 (google-maps-api) 总是得到 ZERO_RESULTS?

security - ubuntu 16.04 LTS 上的 2FA 登录

java - 如何使用 GWT EventBus

java - 如何在 Spring Boot linux 中向类路径提供外部配置资源(数据库属性和 XML 文件)

android - OTP( token )应自动从消息中读取

python - 生成的代码与 PyOTP 示例不匹配

sha1 - 是否可以在 javacard 框架 2.2.1 版本中使用 'ALG_HMAC_SHA1' 类中的 'Signature' 方法?

ios - iOS 应用程序是否可以与 Google Authenticator 通信?

google-authenticator - 为什么 Microsoft Authenticator 在使用电子邮件作为标签而不是颁发者时显示电子邮件域?