首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何生成一次密码(OTP / HOTP)?

如何生成一次密码(OTP / HOTP)?
EN

Stack Overflow用户
提问于 2011-03-02 14:55:34
回答 2查看 29.1K关注 0票数 13

我们决定开始多因素认证工作,为客户发布iPhone、安卓和黑莓应用程序。

想想Google认证器的一次性密码系统吧。

通过使用基于帐户秘密密钥的SALT加上设备序列号(或其他唯一标识符),我可以获得如何生成唯一的字符串

但是,有没有人知道你怎样才能像谷歌那样产生一个独特的、短的数字呢?和/或有人有任何良好的链接,以实现这类事情的文章?

非常感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-29 17:30:50

最后,我发现这在RFC 4226中有很好的说明,关于整数转换,可以使用按位操作见第7页来完成,本质上它与下面的答案相同。

在一个关于堆栈溢出的另一篇文章上下文中存在关于堆栈溢出的另一篇文章,如果您处于类似的位置,这可能是值得一读的。

在C# i中,基本上是散列一个时间标识符(即以秒为单位的当前时间除以30 -以获得对当前30秒间隔有效的长时间)。然后用我的密匙作为盐来打散这个。

然后..。

代码语言:javascript
复制
// Use a bitwise operation to get a representative binary code from the hash
// Refer section 5.4 at https://www.rfc-editor.org/rfc/rfc4226#page-7            
int offset = hashBytes[19] & 0xf;
int binaryCode = (hashBytes[offset] & 0x7f) << 24
    | (hashBytes[offset + 1] & 0xff) << 16
    | (hashBytes[offset + 2] & 0xff) << 8
    | (hashBytes[offset + 3] & 0xff);

// Generate the OTP using the binary code. As per RFC 4426 [link above] "Implementations MUST extract a 6-digit code at a minimum 
// and possibly 7 and 8-digit code"
int otp = binaryCode % (int)Math.Pow(10, 6); // where 6 is the password length

return otp.ToString().PadLeft(6, '0');

对于那些不知道的人来说,Google是一个开源项目--您可以使用在这里浏览源代码

票数 10
EN

Stack Overflow用户

发布于 2011-03-02 15:11:05

嗯,没有是独一无二的。它只需要有一个公平的熵。这意味着获得相同字符串的机会相当低。

这样做的一种方法是取散列并切断一定数量的整数:

代码语言:javascript
复制
var hash = sha1(salt + device + secretKey);
var numbers = base_convert(hash, 16, 10); // Convert hex string to a integer
var key = numbers % 100000; // Limit to 5 digits (you can change this on need)

只需记住把数字放出来,如果太短,就用文字0开头。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5169253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档