我们决定开始为多因素身份验证开展工作,为我们的客户发布iPhone,Android和Blackberry应用程序.
想想Google Authenticator的一次性密码系统.
我可以通过使用基于帐户密钥加上设备序列号(或其他唯一标识符)的SALT进行散列来生成唯一字符串.
但有没有人知道如何以谷歌的方式生成一个独特的短数字?和/或有没有人有任何关于实现这种事情的文章的良好链接?
非常感谢
isN*_*247 10
最后,我发现这在RFC 4226中有很好的记录,关于整数转换,这可以使用第7页所示的按位操作来完成,基本上它与下面的答案中显示的相同.
有关于计算器另一篇文章在C#背景下,这可能是值得一读,如果你是在一个类似的立场对此.
在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');
Run Code Online (Sandbox Code Playgroud)
对于那些不知道的人,Google Authenticator是一个开源项目 - 您可以在这里浏览源代码.
那么,它不具有是唯一的.它只需要有相当多的熵.这意味着获得相同字符串的可能性相当低.
这样做的一种方法是获取哈希并切断一定数量的整数:
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)
Run Code Online (Sandbox Code Playgroud)
只记得留下数字,0如果它太短,它就以文字开头.