我想了解RSA令牌(SecurID)是如何工作的,那里使用的算法是什么,它是否与常规RSA加密/解密的算法相同?
维基引用
RSA SecurID认证机制由一个"令牌"组成——硬件(例如USB加密狗)或软件(软令牌)——分配给计算机用户,并使用内置时钟和卡的工厂编码的随机密钥(称为"种子")以固定的间隔(通常为60秒)生成认证代码。每个令牌的种子是不同的,并在购买令牌时加载到相应的RSA SecurID服务器(RSA Authentication Manager,以前的ACE/server) 1。
所以,它可能与RSA公钥算法有关。对SecurID的真实内部知之甚少,但有一些分析,例如初始SecurID分析,以及维基百科SecurID页面底部的更多信息。
此外,硬件令牌是防篡改的,因此几乎不可能复制被盗的令牌。
更新:由于eyaler,经典SecurID中没有任何公钥/私钥;它们是基于"共享秘密",而不是基于非对称算法。维基百科说,AES-128的变体用于从密钥("种子")生成令牌代码。密钥编码为key at factory
你可以在http://seclists.org/bugtraq/2000/Dec/459
看看它是怎么做的。(过于简化的)机制是
hash = <some initial value>
every x seconds do:
hash = hashfunction(hash + secret_key)
print hash
我可以给你一个暴雪移动认证器是如何工作的感觉,因为他们的代码是开源的。(归档)
基本要点是:
- 使用各种秘密生成哈希
- 还包括从某个开始时间(例如1970年1月1日)开始的30秒间隔的数量
String GetCurrentFOBValue()
{
// Any code is released into the public domain. No attribution required.
// Calculate the number of intervals since January 1 1970 (in UTC)
// The Blizzard authenticator rolls over every 30 seconds,
// so codeInterval is the number of 30 second intervals since January 1 1970.
// RSA tokens roll over every minute; so your counter can be the number
// of 1 minute intervals since January 1, 1970
// Int64 codeInterval = GetNumberOfIntervals();
Int64 codeInterval = (DateTime.Now - new DateTime(1970,1,1)).TotalSeconds / 30;
// Compute the HMAC_SHA1 digest of the code interval,
// using some agreed-upon 20-bytes of secret key material.
// We will generate our 20-bytes of secret key material by
// using PBKDF2 from a password.
// Blizzard's mobile authenticator is given secret key material
// when it enrolls by fetching it from the web-site.
Byte[] secret = PBKDF2("Super-secret password that our FOB knows", 20); //20 bytes
// Compute a message digest of codeInterval using our shared secret key
Byte[] hmac = HMAC(secret, codeInterval);
// Pick four bytes out of the hmac array, and convert them into a Int32.
// Use the last four bits of the digest as an index
// to which four bytes we will use to construct our Int32
int startIndex = hmac[19] & 0x0f;
Int32 value = Copy(hmac, startIndex, 4).ToUInt32 & 0x7fffffff;
// The blizzard authenticator shows 8 digits
return String.Format("%.8d", value % 100000000);
// But we could have just as easily returned 6, like RSA FOBs do
return String.Format("%.6d", value % 1000000);
}
@VolkerK的答案链接到描述"64位"RSA令牌算法的C代码,该令牌使用本质上自定义的算法(反向工程~2000)。
然而,如果你对更现代的"128位"令牌(包括无处不在的SID700硬件令牌和等效的软令牌)所使用的算法感兴趣,那么看看stoken的源代码,这是一个彻底记录其工作原理的开源项目;securid_compute_tokencode
是主要入口
基本上,算法是这样工作的:
- 从当前时间和序列号生成密钥
- 重复使用128位AES加密密钥/种子
- 从输出的十进制表示中提取数字,并添加PIN以进行良好的测量
这与Google Authenticator, YubiKey, Symantec VIP access等中使用的开放标准TOTP算法(Initiative For open Authentication的一部分)并没有什么不同. ...只是MOAR SPESHUL和专有的EKSTRA SECURITEH!
可参考RFC TOTP:基于时间的一次性密码算法
如上所述,RSA令牌(SecurID)中使用的确切算法是TOTP(基于时间的一次性密码算法),一种哈希算法。
种子(可能由AES-128的变体生成)在我们使用它之前已经保存在令牌中。