random - 有没有办法使用 [u8; 64]数组?
问题描述
原始问题:
我目前正在尝试用 rust 编写一个库 - 将其编译为 WASM - 用于将 bip39 助记密码短语转换为 Arweave JWK。我目前正在使用tiny-bip39和RSA。
根据RSA上给出的示例使用 RSA 生成私钥时,我想根据我传递给函数的助记密码来播种 rng。我尝试通过简单地从tiny-bip39生成的助记符对象中获取种子来实现这一点,但这似乎生成了&[u8]
一个长度为64
. 但是,Seed 被定义为[u8; 32]
,并且无需编写自己的 rng,我无法弄清楚如何使用 len64
种子。
#[wasm_bindgen]
pub fn get_key_from_mnemonic(phrase: &str) {
let mnemonic = Mnemonic::from_phrase(phrase, Language::English).unwrap();
assert_eq!(phrase, mnemonic.phrase());
let seed = Seed::new(&mnemonic, "");
let seed_bytes = seed.as_bytes();
let mut rng = ChaCha12Rng::from_seed(seed_bytes);
[...]
}
是否有允许 len64
种子的加密安全 rng?
我试着简单地尝试,但这似乎不起作用,这是有道理的。
let seed_bytes: <ChaCha12Rng as SeedableRng>::Seed = seed.as_bytes().try_into().unwrap();
编辑:
我想出了一个解决方案,除了随机数生成之外,它似乎在各个方面都有效。
let mnemonic = Mnemonic::from_phrase(phrase, Language::English).unwrap();
assert_eq!(phrase, mnemonic.phrase());
let seed = Seed::new(&mnemonic, "");
let seed_bytes = seed.as_bytes();
let mut seed_buf: [u8; 32] = Default::default();
let mut hmac_drgb = HmacDRBG::<Sha256>::new(&seed_bytes, &[], &[]);
hmac_drgb.generate_to_slice(&mut seed_buf, None);
let mut chacha = ChaCha20Rng::from_seed(seed_buf);
let modulus_length = 4098;
let rsa_private_key = RsaPrivateKey::new(&mut chacha, modulus_length).unwrap();
let der = rsa_private_key.to_pkcs1_der().unwrap();
let jwk = JWK {
modulus: der.private_key().modulus.as_bytes().to_vec(),
public_exponent: der.private_key().public_exponent.as_bytes().to_vec(),
private_exponent: der.private_key().private_exponent.as_bytes().to_vec(),
prime1: der.private_key().prime1.as_bytes().to_vec(),
prime2: der.private_key().prime2.as_bytes().to_vec(),
exponent1: der.private_key().exponent1.as_bytes().to_vec(),
exponent2: der.private_key().exponent2.as_bytes().to_vec(),
coefficient: der.private_key().coefficient.as_bytes().to_vec(),
};
当我试图重写arweave-mnemonic-keys提供的一些功能时,我试图通过所有依赖项,找出我需要哪些 rust 模块,并认为我已经设法弄清楚除了如何生成之外的所有内容RSA算法的随机数。
我试过浏览 node-forge/lib/rsa.js 文件,发现了这个片段:
function generateRandom(bits, rng) {
var num = new BigInteger(bits, rng);
// force MSB set
var bits1 = bits - 1;
if(!num.testBit(bits1)) {
num.bitwiseTo(BigInteger.ONE.shiftLeft(bits1), op_or, num);
}
// align number on 30k+1 boundary
num.dAddOffset(31 - num.mod(THIRTY).byteValue(), 0);
return num;
}
但是,我不确定如何在 rust 中重现它。到目前为止,我已经尝试使用ChaCha8Rng
、ChaCha12Rng
、ChaCha20Rng
和Pcg64
,它们都没有产生想要的结果。
解决方案
这取决于 CSPRNG。如果您使用 HMAC-SHA-512 播种 HMAC DRBG,那么这将是一个完全正常的输入量。但是,在您的情况下,CSPRNG 是 ChaCha,它被配置为具有 256 位密钥。
如果这个助记词是从 CSPRNG 生成的并且具有足够的熵,那么您所需要的只是一个简单、直接的密钥派生函数,如 HKDF。您可以将HKDF与 SHA-256 或 SHA-512 一起使用,种子作为输入密钥材料,无盐,输出密钥材料大小为 32 字节。然后,您可以使用它来播种您的 CSPRNG。
您还需要一个信息字符串,通常是一些用于此目的的文本字符串。我喜欢使用版本号来保证未来的发展,因此您可以使用“v1 PRNG 种子”之类的东西。
我在这里的建议是,由于您有一个 64 字节的输入种子,因此使用 SHA-512 的 HKDF 是最好的,因为如果您最终需要为其他数据播种,它可以避免丢失熵。此外,虽然 ChaCha12Rng 是默认设置,但 ChaCha20Rng 更保守,可能适合生成长期密钥。
推荐阅读
- javascript - 商店调度后VueJS发出不工作
- python-3.x - 如何使用 Python 提取 Workday 职位发布链接?
- python - 禁止 Django 直接分配到多对多集合的反面。使用 .set()
- laravel - 为什么我在使用 Laravel Websockets 包时遇到问题?
- c++ - 使用 nano.specs 时 libc.a 和 libc_nano.a 之间的多个函数定义
- javascript - msSaveBlob 文件损坏
- reactjs - 无法从我的 next.js 应用程序获取我的strapi 数据
- amazon-web-services - 如何减少 AWS MediaConvert 中 m3u8 的每个 .ts 块的持续时间?
- npm-install - npm WARN @loopback/eslint-config@1.1.2 需要 eslint@^5.16.0 的对等点,但没有安装。您必须自己安装对等依赖项
- azure - 使用 Azure.Identity Lib DefaultAzureCredential.GetTokenAsync 时如何强制刷新访问令牌