You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Rust Ring AEAD解密密文?解密报错求助

Ring库AEAD解密失败的排查与解决

核心错误原因

你犯了AEAD加密的一个关键错误:解密时使用了与加密完全不同的随机nonce。

AEAD算法(如AES-GCM)要求:加密和解密必须使用完全相同的nonce,同时AAD(附加认证数据)和密钥也必须完全一致。nonce的作用是保证相同密钥下相同明文加密出不同密文,但解密时只有用同一个nonce才能正确还原明文并验证标签。你生成两个随机nonce分别用于加密和解密,直接导致解密上下文不匹配,触发验证失败(也就是你看到的Unspecified错误)。

修正后的代码

把解密用的nonce替换成加密时的同一个nonce即可,同时密钥不需要重新创建(当然重新创建也没问题,只要用同一个密钥数据):

use ring::aead::{UnboundKey, AES_256_GCM, LessSafeKey, NONCE_LEN, Aad, Nonce};
use ring::rand::{SystemRandom, SecureRandom};

fn main() {
    let mut secret = vec![0u8; AES_256_GCM.key_len()];
    let mut nonce_bytes = vec![0u8; NONCE_LEN];
    let rng = SystemRandom::new();
    rng.fill(&mut secret).unwrap();
    rng.fill(&mut nonce_bytes).unwrap();
    
    let nonce = Nonce::try_assume_unique_for_key(&nonce_bytes).unwrap();
    let key = LessSafeKey::new(UnboundKey::new(&AES_256_GCM, &secret).unwrap());
    
    let mut payload = Vec::from(String::from("Test"));
    let aad = Aad::from(b"test_aad");
    
    println!("明文: {:?}", payload);
    key.seal_in_place_append_tag(nonce, aad, &mut payload).unwrap();
    println!("加密后(密文+标签): {:?}", payload);
    
    // 解密时复用加密用的nonce、AAD和密钥
    key.open_in_place(nonce, aad, &mut payload).unwrap();
    println!("解密后明文: {:?}", payload);
}

额外排查思路

如果后续再遇到类似错误,可以从以下几点逐一验证:

  • nonce一致性:确保解密用的nonce和加密时完全相同,字节内容无任何差异(nonce不需要保密,通常和密文一起传输)
  • AAD一致性:加密和解密的附加认证数据必须完全一致,包括字节长度和内容
  • 密钥一致性:加密和解密使用的密钥必须是同一个,注意密钥的存储、传输过程中没有被修改
  • 密文完整性:解密前不要修改密文或标签的任何字节,哪怕一个字节的改动都会触发验证失败

内容的提问来源于stack exchange,提问作者Fred Kerr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:22:49