我们决定开始研究多因素身份验证,为我们的客户发布iPhone,Android和Blackberry应用程序。
考虑Google Authenticator的一次性密码系统。
我可以通过使用基于帐户密钥加上设备序列号(或其他唯一标识符)的SALT进行散列来生成唯一的字符串。
但有没有人知道如何以谷歌的方式生成一个独特的短号码?和/或是否有人有任何关于实现此类事情的文章的良好链接?
非常感谢
答案 0 :(得分:10)
最后我发现这在RFC 4226中有很好的记录,关于整数转换,这可以使用按位运算shown on page 7完成,基本上它与显示的相同。回答如下。
在C#上下文中有another post on stackoverflow,如果你处于类似的位置,可能值得一读。
在C#中我基本上散列了一个时间标识符(即以秒为单位的当前时间除以30 - 得到一个对当前30秒间隔有效的长度)。然后使用我的密钥作为SALT对此进行哈希处理。
然后......
// Use a bitwise operation to get a representative binary code from the hash
// Refer section 5.4 at http://tools.ietf.org/html/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身份验证器是一个开源项目 - 您可以browse the source code here。
答案 1 :(得分:6)
嗯, 不是唯一的。它只需要有相当多的熵。这意味着获得相同字符串的可能性相当低。
这样做的一种方法是使用哈希并切断一定数量的整数:
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
开头。