编辑:明显是盲目的,所以我错过了。OpenSSL 已经为其自己的内部 PRNG 提供了一个接口,该接口以机器的/dev/urandom. 只需这样做:
openssl rand 10000000
产生一千万个伪随机字节。在我的笔记本电脑上,这似乎比 快 3 倍/dev/urandom,即 11 MByte/s 左右。如果这对您来说还不够快,请继续阅读。
原始回复:
这实际上取决于所涉及的硬件和上下文。既然您在谈论 bash 脚本/dev/urandom和 OpenSSL,我想:
- 你使用 Linux。
- 您想生成一个充满伪随机字节的大文件。
- 您需要一个解决方案,它是现有“正常”包的脚本程序集,而不是编程解决方案。
事实上,如果你能写自己的C代码,你最好的选择将是CTR模式与为AES加密AES-NI指令(最近的PC上提供这些指令),或专用的流密码(的例如,一个这些)。在 2.4 GHz Core2 CPU 上,我可以从 Sosemanuk 中获得 700 MByte/s 的伪随机字节。我以后假设您仅限于脚本。
使用 OpenSSL 加密并不是一个坏主意,但有一些细节:
- 随机化每个块的长度是一个无用的复杂化。
- 无需去AES-256;AES-128 已经很好了。AES-256 比 AES-128 慢 40%,并且在安全性方面没有增加任何实际改进。
- 当使用 CBC 加密一长串零时,您实际上是在 OFB 模式下运行块密码(加密一个块,一次又一次地加密它)。只要您保持低于2 n/2限制,这是合理的,这意味着使用 AES(128 位块)您不会使用超过2 64 个16 字节块(即 2.5 亿 TB)的块。有可能你无论如何都达不到它。从这个意义上说,“重新播种”并不是真正需要的。
- 当您“重新播种”时(如果您决定维护此功能,这是不必要的),请使用
/dev/urandom,而不是/dev/random. /dev/urandom对密码学来说很好(操作系统启动脚本确保内部 PRNG 被正确播种),尽管实施时存在误入歧途的疑虑/dev/random。另一方面,/dev/random可能会阻塞,因此非常慢(没有什么比阻塞进程更慢的了)。
- 当心字符串。
bash使用字符串;/dev/random并/dev/urandom返回bytes,包括值为 0 的字节。这可能会导致人为截断密钥,并降低安全性。这不好。相反,您应该将字节编码为十六进制,-K并-iv使用openssl.
- OpenSSL 可以添加一个以 8 个固定字节开头的标头(因此完全非随机)。
-K如果您使用and ,它不会这样做-iv。
- OpenSSL 还将使用一些填充,因此您将在最后获得一个额外的 16 字节块(这不是问题;填充在明文上,并且加密“随机化”它)。
这导致以下脚本:
#!/bin/sh
key=$(dd if=/dev/urandom bs=16 count=1 2>/dev/null | md5sum | cut -d' ' -f1)
iv=$(dd if=/dev/urandom bs=16 count=1 2>/dev/null | md5sum | cut -d' ' -f1)
dd if=/dev/zero bs=65536 count=8192 2>/dev/null | openssl aes-128-cbc -K $key -iv $iv
调用时,此脚本会输出正好 536870928 个伪随机字节的序列,这些字节适合用于加密目的。随意修改bs和count参数,但请记住,这dd将分配一个大小为 的 RAM 缓冲区bs,因此您通常希望保持bs较小,但不要太小以避免过多往返内核(8192 到 65536 通常是好的值)。
我在这里使用 MD5 只是为了方便字节到十六进制的转换(MD5 的已知缺点在这种情况下对安全性没有任何影响)。
该脚本应该适用于任何体面的 Linux 安装。它只使用默认情况下应该存在的包。在我不是很强大的笔记本电脑上,这个脚本以每秒 73 MBytes 的速率生成伪随机字节,这还不错,可能足以满足您的目的(如果这还不够,那么您可能会遇到其他问题 I/ O 瓶颈)。