1

我的程序连接到服务器,服务器的公钥是已知的。然后程序将 AES 密钥与初始化向量一起加密,并将其发送到服务器。服务器解密消息,从现在开始使用 AES 加密对话。

我的问题是关于如何生成 IV。如果我采取天真的方式并用当前时间播种一个伪随机生成器,攻击者可能会对 IV 做出一些非常好的猜测,这可诅咒不是我想要的。

由于硬件随机生成器不仅速度慢,而且并非随处可用,我想采用不同的方法。当客户端程序第一次启动时,我让用户随机移动一些鼠标,就像 TrueCrypt 一样。我现在保存由鼠标移动创建的那些“随机位”,当我需要生成器时,我会将它们用作种子。当然,每次我将随机位用作种子时,都必须更新它们。这是我的问题:我考虑将生成的前几个随机位保存为新的“随机位”。(所以他们习惯于在下次软件启动时初始化随机引擎。)现在我不确定这是否足够随机,或者伪随机生成器是否会在这里显示可猜测的模式。(我可能会使用 std::mt19937 http://en.cppreference。)

编辑:链接模式发生变化,所以我希望它适用于具有“最高”要求的模式。如果我没记错的话应该是CBC。

请注意:我正在编写的软件纯粹是实验性的。

4

3 回答 3

2

使用加密 PRNG,就像您对密钥所做的那样。

在 Windows 上使用CryptGenRandom/ RtlGenRandom,在 Linux/Unix 上使用/dev/urandom. 那些由操作系统播种,所以你不需要照顾它。

如果您真的想创建自己的 PRNG,请查看Fortuna。不要使用梅森捻线机。

于 2012-11-24T11:38:50.630 回答
1

您应该明确计划使用哪种链接模式。初始化向量的安全要求强烈依赖于此。

例如,在 CBC 模式下,IV 必须是不可预测且唯一的。对于 CTR 模式,它只能是唯一的,不一定是不可预测的。

于 2012-11-24T11:32:30.237 回答
-1

伪随机生成器适用于您不希望用户能够预测结果的事情(例如游戏中的掷骰子),但对于您不希望计算机能够计算它的情况则毫无价值。对于密码学,根本不要使用伪随机性。

如果你想要随机性,你需要实际的随机数据。正如您所写,鼠标移动是一个很好的来源。鉴于您不谈论 /dev/random,我认为您正在 Windows 上运行,不幸的是,它在运行时不会收集随机性。所以你必须自己做这件事。根据用例,您可以在启动时运行一个随机守护程序,它会不断收集随机数据并允许您的程序在需要时检索它,或者您可以要求用户在程序启动时进行一些鼠标移动。

或者您可以决定,如果 Windows 不希望您拥有真正的随机数据,您就不想使用 Windows,但我认为这不是一个选择。;-)

于 2012-11-24T09:15:34.397 回答