使用微时间作为唯一标识符的潜力


Potential of using microtime as a unique identifier

如果用户提交了一个微时间值,则服务器会话将跟踪该值。是否可以跟踪微时间,类似于RSA风格的密码短语,用于加密从服务器发送和接收的数据。

这是自动/动态生成密码短语的可靠方法吗。

不确定这是否是正确的堆栈。

我认为这里有几个问题,所以我会在实际问题之前解决它们:

使用微时间作为唯一标识符

只有当您从未在同一微秒中生成两个标识符时,才有效。您的时间函数实际测量的微秒时间是单调的(总是增加的)。这三个都是不可靠的假设。

在同一微秒内生成两个标识符是非常可能的。您的时间函数可能没有您认为的精度,或者数据类型所暗示的精度(例如,它可能总是返回以000结尾的值)。最后,像夏令时和闰秒这样的东西可能会使时间倒退,最终会重用id。

所以,不,微时间作为唯一标识符在生产中不是一个好主意。

RSA式密码短语

RSA是一种非对称密钥加密系统。它允许各方拥有源自真正随机数的公钥和私钥,并以合理的安全性将加密和/或签名的数据发送给对方。RSA公钥如下(十六进制模数):

af 46 03 ce c7 13 e6 2e 93 d8 56 91 b1 31 8d 0a 
22 c1 f0 eb 4f 5e ef 0d f6 20 32 b9 a4 4e 87 f9 
d2 d2 44 51 b0 df 30 50 c9 35 4e 68 19 84 fb 98 
33 aa 05 4b 7e fb 57 c5 b6 2e a8 4b 04 ca cf 5e 
2e e5 9e 1b ca b7 60 c5 58 2c b0 df c4 6b 0d b1 
2c 33 97 73 54 61 2b 9a 1b b1 dc 5d 10 a9 c4 c8 
f7 6c e3 55 6e b5 0e 61 3b 35 24 0b 89 1e 32 a2 
75 69 4e 97 40 68 ee 23 48 f2 71 9f c7 7e e2 9d 
6c 22 55 36 24 64 a4 f0 b6 52 58 5a 9a 44 e7 3b 
2a d5 ed 95 63 f8 1d a8 4d 45 9b 5d c2 f2 f9 74 
81 06 18 d5 b1 fb b0 7e 5d 50 1f 63 5c a0 73 f5 
22 b2 57 64 03 e6 b7 0f 6f b7 58 0b 57 80 56 51 
65 9f f5 09 61 63 29 62 4d 30 02 3a 64 10 2d 95 
b8 12 36 04 58 c5 d7 1d 95 e2 21 3c b0 b3 93 35 
b2 b1 f9 6d 7e 20 66 b2 68 33 e9 50 a8 15 1e 0a 
80 9a 3c 19 dd cc 79 35 a8 8c 1b 61 33 5d 12 2f 

密码短语是用户(通常)选择的一长串字母和符号,用于提供身份验证或生成可重复的随机数(例如,比特币的大脑钱包)。密码短语如下:

correct horse battery staple

"RSA样式密码短语"是一个非常奇怪的表达,我不知道你的意思,但这表明你可能有误解。

用于散列从服务器发送和接收的数据

为什么要对服务器发送和接收的数据进行哈希处理哈希意味着以一种难以猜测的可重复方式,取一些字节,并将其篡改到无法识别的短尺寸。像TLS这样的安全通道可以在内部使用哈希,但使用它的程序员应该完全看不到它

也许你指的不是散列,而是加密。加密就是获取一些数据和密钥,并以只有持有密钥的人才能撤消该过程的方式对它们进行篡改。另一方面,散列没有密钥,(希望)也没有撤消的方法。这可能看起来像是挑剔,但密码学是微妙,需要高度关注。


抛开抱怨不谈,回答你的问题。

如果我理解正确,您希望使用微秒精度的系统时钟来生成某种密钥材料(密钥、密码短语、随机数或等效物),以确保客户端-服务器通信的安全(哈希以确保完整性、加密或类似)。

这可能是有道理的,因为攻击者永远不会知道您生成密钥的确切微秒。数据类型相当大,可能是128位,相当于一个好密钥的大小。

但是时间不是随机的。攻击者不知道确切的微秒,但他们可以猜测。如果他们知道时间,他们只有60 * 60 * 1000 * 1000 = 3600000000,不到40亿的可能性。对于密码学,我们认为攻击者可以在不到一秒钟的时间内做出这么多猜测。40亿只是32位的安全性,对于保护数据来说是微不足道的。

根据现代最佳实践提出的解决方案:

  • 如果您只需要唯一的标识符,则不涉及密码学:使用UUID版本4,它几乎在所有语言中都有实现。它们的碰撞几率为5316919883139663491615228241121378304中的一个,这应该足够了。不过,它们是可以猜测的。

  • 如果您需要一个唯一/随机值来进行加密(您是一个知道自己在做什么的密码学家):在Linux上使用/dev/urandom,在大多数语言中都可以作为CryptoRandom库使用。

  • 如果您想要客户端和服务器之间的安全通道:请使用TLS。您可以很快从StartSSL或Let's Encrypt获得免费证书。我建议使用像nginx这样的代理来处理TLS/SSL之类的东西,然后可以在主应用程序中使用纯HTTP。

  • 如果您想以其他方式安全地交换数据:请使用已移植到许多语言的NaCl库。它具有使用安全默认值和最先进的加密技术加密和签名数据的功能。


这不是要抨击你。只是密码学很难,你只有一次机会。所以请小心。如果你是一名密码学家或想了解更多信息,我建议你向安全社区咨询。