如何生成密钥以使HMAC SHA512的TOTP符合RFC6238和RFC4086?

时间:2018-10-24 08:31:29

标签: java hmac totp

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

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

因此,为实现上述目的,我修改了RFC6238 RC6238 TOTP Algo

的Java代码。

要获得TOTP,我使用online converter tool和一些生成相同的128个字符长度的十六进制代码的代码将共享密码“ abc@example.comTEXT5”转换为HMAC-SHA512。

发出请求时,始终会回答“ TOTP错误”。

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

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

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

如何为我的共享机密“ abc@example.comTEXT5”获得此类seed64? 我修改后的代码是10 digit TOTP

我感谢大家的帮助!

1 个答案:

答案 0 :(得分:0)

Appendix A of RFC 6238中的示例64字节种子是Appendix B中提供的ASCII机密<!DOCTYPE html> <html> <body> <link rel="stylesheet" href="https://cdn.fluidplayer.com/v2/current/fluidplayer.min.css" type="text/css"/> <script src="https://cdn.fluidplayer.com/v2/current/fluidplayer.min.js"></script> <video id="short" height="225" loop controls> <source src="wrestling.mp4" type="video/mp4"/> </video> <video id="short" height="225" loop controls> <source src="wrestling.mp4" type="video/mp4"/> </video> <video id="short" height="225" loop controls> <source src="wrestling.mp4" type="video/mp4"/> </video> </body> <script type="text/javascript"> var myFP = fluidPlayer( 'short', { layoutControls: { fillToContainer: false, primaryColor: false, posterImage: false, autoPlay: false, playButtonShowing: true, playPauseAnimation: true, mute: false, logo: { imageUrl: null, position: 'top left', clickUrl: null, opacity: 1, mouseOverImageUrl: null, imageMargin: '2px', hideWithControls: false, showOverAds: false }, htmlOnPauseBlock: { html: null, height: null, width: null }, allowDownload: false, allowTheatre: false, playbackRateEnabled: false, controlBar: { autoHide: true, autoHideTimeout: 1, animated: false }, }, vastOptions: { } } ); </script> </html>的HEX编码版本,其中包含真值表。

12345678901234567890

如果要使用相同的模式转换共享机密,则使用附录A中提供的示例代码时,可以将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 转换为字符串格式的HEX。

这将出现在以下十六进制字符串中:

abc@example.comTEXT5

要构建用于SHA-512哈希的示例64字节种子,将重复最初的20个字节以使总共64个字节达到SHA-512哈希的最佳密钥长度。

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

616263406578616D706C652E636F6D5445585435

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

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

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

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

您似乎已经对其中的大部分代码进行了编码,但是如果您正在寻找一些其他的Java示例,则以下链接是一个GitHub项目,该项目具有一个简单的实用程序类和一系列测试。 https://github.com/FusionAuth/fusionauth-2FA