aes_gcm_siv 32 字节密钥要求的解决方法?

问题描述

使用任何不是 32 字节的密码会使程序出现以下情况:

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

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

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

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 个字符长的硬编码密钥似乎很有欺骗性。

解决方法

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

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