Rng 从操作系统获得随机性与加密 rng 的

Rng getting randomness from operating system vs crypto rng's

这个问题确实与密码学堆栈交换上可能发布的内容有很多重叠,但它主要是特定于 Rust 的,因此我将其发布在这里。

所以我有一个应用程序需要使用 DH 密钥对。

重要的是这个项目只是学术性的,这个代码不会在任何产品环境中使用。

我在一个已经使用名为 x25519_dalek 的箱子的上下文中工作,因此继续使用该资源来创建我自己的密钥对是有意义的。

文档给出了这个密钥创建示例:

use rand_core::OsRng;
use x25519_dalek::{EphemeralSecret, PublicKey};

let alice_secret = EphemeralSecret::new(OsRng);
let alice_public = PublicKey::from(&alice_secret);

这很好,很直接,我们只需将一个 rng 传递给临时秘密即可获得密钥,然后从那里获得 PK。

但这就是我开始怀疑的地方。 Osrng 使用 OS 来产生一些随机性。但是 rand_core 的文档没有提及它是一个加密安全的 CSPRG。

另一方面,我之前使用过 rand 包,它是 Stdrng rng,为 IV 创建随机数字列表。因为这个 rng 是 mentioned specifically as a crypto secure rng

use rand::{rngs::StdRng, Rng, SeedableRng,};
use rand_core::{RngCore, OsRng, CryptoRng,};
fn main() {
  let mut rng : StdRng = StdRng::from_entropy();
  let seed = rng.gen::<[u8;32]>();
}

这让我想知道使用像 OSrng 这样的基本 rng 是否可以安全地用于创建键控 material。或者,如果我宁愿拍摄一个用于加密的 rng。

如果我确实应该为创建键控找到另一个随机源 material,那么我有一个关于如何在 Rust 中执行此操作的问题(我对 Rust 很陌生) .

我有点不清楚我应该能够在 EphemeralSecret 上为构造函数提供哪种 rngs。它的签名如下所示:

pub fn new<T: RngCore + CryptoRng>(mut csprng: T) -> Self {

然后我尝试从 rand crate 传入 Stdrng

use rand::{rngs::StdRng, Rng, SeedableRng,};
use rand_core::{RngCore, OsRng, CryptoRng,};
fn main() {


  let secretk = EphemeralSecret::new(StdRng);
}

失败并显示 "expected value, found struct StdRng" 消息,这对我来说很奇怪,因为 OsRng 也是一个结构。

我也试过初始化一个 rng 并传递它:

  let mut rng : StdRng = StdRng::from_entropy();
  let seed = rng.gen::<[u8;32]>();

  let secretk = EphemeralSecret::new(rng);

所以第二个问题是,有人知道我是否可以使用标准 rand crate 中的加密安全随机源在 x25519_dalek 中创建键控 material 吗?

OsRng 应该是加密安全的。它实现了 CryptoRng,这是一个仅为加密安全 PRNG 实现的特性,它由 getrandom 板条箱支持,它总是使用系统的(或者,在 WebAssembly 的情况下,是环境的)CSPRNG。

CSPRNG 始终是明智的选择,但如评论中所述,它并不总是很快,因为它涉及每个操作的系统调用,并且系统的 CSPRNG 并不总是很快,任何一个。在这种情况下,您可以使用 ThreadRng,它会更快并且加密安全。