返回介绍

1.足够随机了吗?

发布于 2024-12-29 22:37:17 字数 2350 浏览 0 评论 0 收藏 0

当你调用 new Key() 时,实际上是在用 PRNG(伪随机数生成器)来产生私钥。在 windows 平台上,就是用系统提供的 RNGCryptoServiceProvider。.

在安卓上,我使用 SecureRandom,实际上你可以自己实现 RandomUtils.Random 然后使用它。

在 IOS 上,我还没用实现,你需要自己实现 IRandom。

对一台电脑来说,随机是很难的。但是最大的问题是,几乎不可能知道一串数字是否真的是随机的。

如果有个恶意软件修改了你的 PRNG(当然可以预测你将产生的随机数),当你发现时已经太迟了。

这就意味着跨平台的 PRNG 实现(就好像使用电脑时钟加上 CPU 速度)是危险的,但是当你发现时已经太迟了。

出于效率的考虑,大多数 PRNG 工作方法都是一样的:选择一个随机数,称为种子,然后每次你需要的时候,一个可预测的规则就会为你产生下一个数字。

种子的随机程度由熵的测量来定义,但是熵的大小同时取决于观察者。

假设你从时钟时间产生一个种子,并且你的时钟分辨率可能是 1ms。(实际上是更多,大约 15ms)

如果黑客知道上星期你产生了 key,那么你的种子有 1000 60 60 24 7 = 604800000 种可能性。

对这个黑客来说,熵就是 LOG(604800000;2) = 29.17 bits。

在我的家用电脑上遍历这样的数字用不了 2 秒钟,我们把这种遍历叫 暴力攻击 。

然而,如果你使用时钟时间 + 进程 ID 来产生种子, 并且假设有 1024 个不同的进程 ID。

那么,现在黑客就需要遍历 604800000 * 1024 种可能性,大概需要耗时 2000 秒。

然后,如果再加上我打开电脑的时间,就算黑客知道我是在今天打开的话,那也有 86400000 种可能性。

这样的话,黑客需要遍历 604800000 1024 86400000 = 5,35088E+19 种可能性。

可是,注意如果黑客攻击了我的电脑,他就可以获得最后的信息片段,减少数字的可能性,从而减少熵。

熵按照 LOG(possibilities;2) 来测量,所以 LOG(5,35088E+19; 2) = 65 bits。

足够了吗?也许,如果你面临的黑客不知道可能世界里的更多信息的话。

但是既然公钥的哈希是 20bytes = 160bits,比所有地址空间要小,所以你可以做得更好。

注意:增加熵的难度是线性递增的,攻击熵的难度是指数递增的。

一种可以快速产生熵的有趣方法就是人类的干预。(比如移动鼠标)

如果你不完全信任 PRNG 平台(并不奇怪),你可以给 NBitcoin 使用的 PRNG 输出增加熵。

RandomUtils.AddEntropy("hello");
RandomUtils.AddEntropy(new byte[] { 1, 2, 3 });
var nsaProofKey = new Key();

调用 AddEntropy(data) 时 NBitcoin 做的事情如下:

additionalEntropy = SHA(SHA(data) ^ additionalEntropy)

当你产生一个新数字的时候:

result = SHA(PRNG() ^ additionalEntropy)

c. 主要的派生函数

然而,数字的可能性并不是最重要的。最重要的是黑客成功打开你秘钥的时间。这样 KDF 就来了。

KDF, Key Derivation Function 的简称,是一种取得更加坚固秘钥的方法,即便你的熵比较低。

想象一下,你需要产生一个种子,并且黑客知道它存在 10,000,000 种可能性。这样的种子一般情况下很容就被破解了。

但是如果你可以让遍历工作慢一些呢?

一个 KDF 就是一个旨在耗费计算资源的哈希函数,下面是一个例子:

var derived = SCrypt.BitcoinComputeDerivedKey("hello", new byte[] { 1, 2, 3 });
RandomUtils.AddEntropy(derived);

即使你面临的黑客知道熵源就是 5 个字母,他仍然需要运行 Scrypt 以检测可能性,在我的电脑上这需要耗费 5 秒钟。

最后:不信任 PRNG 并不是固执己见,你可以通过增加熵和使用 KDF 来降低攻击的破坏性。

时刻记在心头,黑客可以收集你或者你的系统信息来降低熵。

如果你使用时间戳作为熵源,他就会知道你是上周生成秘钥的,并且你只在上午 9 点到下午 6 点之间使用电脑,这样就可以降低熵。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文