首页 > 解决方案 > aes_gcm_siv 32 字节密钥要求的解决方法?

问题描述

使用任何不是 32 字节的密码都会使程序恐慌:

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `4`,
 right: `32`'

简单的解决方案似乎是用零填充它或将密码从 0 修剪到 31,但为什么呢?我怀疑它有任何安全隐患,因为它不会让你使用超过 32 个字节。除了上述简单的解决方案之外,是否还有其他解决方法可以让用户拥有更长的密码而不是重写板条箱?

以下是我的上下文代码片段:

use aes_gcm_siv::Aes256GcmSiv;
use aes_gcm_siv::aead::{Aead, NewAead, generic_array::GenericArray};

fn encrypt_file(pass: &str, file: &str) {
    println!("{}", pass);
    let key = GenericArray::from_slice(pass.as_bytes());
    let cipher = Aes256GcmSiv::new(&key);
    //...
}

我不喜欢https://docs.rs/aes-gcm-siv/0.9.0/aes_gcm_siv/中给出的使用示例。使用 32 个字符长的硬编码密钥似乎很具有欺骗性。

标签: rustaes-gcm

解决方案


您的部分问题是您直接使用密码作为密钥。你不想那样做。AES 需要 128 位、192 位或 256 位密钥,理想情况下,您希望它与随机密码无法区分,而密码通常不会。

如果你有一个低熵的秘密,你可能想要使用像 Argon2id 这样的东西来获取该密码和一个足够长的随机盐来派生密钥。如果您有一个包含大量熵的强机密,那么您可以使用 HKDF 之类的东西来生成密钥。如果您执行其中任何一项操作,您可以生成一个正好 32 字节长的密钥,并且,如果您愿意,还可以生成一个用于加密的随机 nonce。由于您使用的是 AES-GCM-SIV,因此您也可以使用随机随机数并以这种方式派生密钥。


推荐阅读