3

我必须向 URL http://example.com/test发出 HTTP POST 请求,其中包含 JSON 字符串作为正文部分、标题“Content-Type:application/json”和“Authorization: Basic userid:password”。用户 ID 是 abc@example.com,密码必须是 10 位基于时间的一次性密码,符合 RFC6238 TOTP,使用 HMAC-SHA-512 作为哈希函数。

令牌共享密钥应为“abc@example.comTEXT5”,不带双引号。

所以,为了实现上面我修改了 RFC6238 RC6238 TOTP Algo的 Java 代码

为了获得 TOTP,我使用在线转换器工具将共享密钥“abc@example.comTEXT5”转换为 HMAC-SHA512 ,以及一些生成相同的 128 个字符长度的十六进制代码的代码

发出请求总是响应“TOTP 错误”。

我注意到我生成了错误的密钥,所以 TOTP 错误。那么,如何生成符合 HMAC-SHA512 和 RFC6238 算法的 Java 代码的正确密钥?

算法中有默认密钥作为种子:

String seed64 = "3132333435363738393031323334353637383930" +
         "3132333435363738393031323334353637383930" +
         "3132333435363738393031323334353637383930" +
         "31323334";

我怎样才能为我的共享秘密“abc@example.comTEXT5”获得这样的种子64?我修改后的代码是10 位 TOTP

我感谢大家的帮助!

4

1 回答 1

4

RFC 6238 附录 A 中的示例 64 字节种子是附录 B12345678901234567890中提供的 ASCII 机密的十六进制编码版本,其中包含真值表。

ASCII 1  2  3  4  5  6  7  8  9  0  1  2  3  4  5  6  7  8  9  0
HEX   31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30

如果您想使用相同的模式转换您的共享密钥,abc@example.comTEXT5如果您使用的是附录 A 中提供的示例代码,您将转换为字符串格式的 HEX。

这将产生以下 HEX 字符串:

616263406578616D706C652E636F6D5445585435

为了构建用于 SHA-512 散列的示例 64 字节种子,重复初始 20 个字节以使总共 64 个字节以实现 SHA-512 散列的最佳密钥长度。

对示例字符串执行相同操作会产生以下种子:

String seed64 = "616263406578616D706C652E636F6D5445585435" +
         "616263406578616D706C652E636F6D5445585435" +
         "616263406578616D706C652E636F6D5445585435" +
         "61626340";

如果您使用示例代码的其余部分来计算时间步长并请求 10 位 TOTP 代码,我认为它会为您工作。

如果您在生产中使用类似的东西,您可能希望使用更随机生成的秘密。

例如,要为 SHA-512 生成 64 字节机密,您可以执行以下操作:

  public static String generateRawSecret(int length) {
    byte[] buf = new byte[length];
    new SecureRandom().nextBytes(buf);
    String rawSecret = Base64.getEncoder().encodeToString(buf);
    return rawSecret.substring(1, length + 1);
  }

  // Random 64 byte secret
  String secret = generateRawSecret(64);

看起来您已经编写了大部分代码,但如果您正在寻找一些额外的 Java 示例,以下链接是一个 GitHub 项目,它有一个简单的实用程序类和一堆测试。https://github.com/FusionAuth/fusionauth-2FA

于 2018-12-21T17:33:21.360 回答