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

如何在Vala中使用GCrypt AES128?代码加密结果不符求排查

Vala+GCrypt AES128 CBC加密结果不符问题排查与修正

问题根源

你的代码存在三个核心问题导致加密结果不符合预期:

  • 未启用PKCS#7填充,CBC模式下无法处理非块大小整数倍的明文(或无法生成符合预期的填充后密文)
  • 调用encrypt时未指定输入数据长度,GCrypt无法确定加密范围
  • 输出缓冲区大小与明文长度一致,无法容纳带填充的加密结果

修正后的代码

using GCrypt;
using Posix;

void main () {
    GCrypt.Cipher.Cipher cipher;
    // 启用PKCS#7填充,配合CBC模式使用
    GCrypt.Error err = GCrypt.Cipher.Cipher.open(out cipher, Cipher.Algorithm.AES128, Cipher.Mode.CBC, Cipher.Flag.SECURE | Cipher.Flag.PKCS7);
    if (err != 0) {
        print("Error: %s\n", err.to_string());
        Process.exit(EXIT_FAILURE);
    }

    string iv = "1111111111111111";
    string key = "2222222222222222";
    
    // 显式传递密钥长度,确保GCrypt识别16字节的AES128密钥
    err = cipher.set_key((uchar[])key.data, key.length);
    if (err != 0) {
        print("Error key: %s\n", err.to_string());
        Process.exit(EXIT_FAILURE);
    }
    
    // 显式传递IV长度,匹配AES块大小(16字节)
    err = cipher.set_iv((uchar[])iv.data, iv.length);
    if (err != 0) {
        print("Error iv: %s\n", err.to_string());
        Process.exit(EXIT_FAILURE);
    }

    string str = "Hello World!!!!!";
    size_t block_size = cipher.get_block_size();
    // 计算填充后的密文长度:块大小的整数倍
    size_t output_size = ((str.length + block_size - 1) / block_size) * block_size;
    uchar[] ary = new uchar[output_size];
    print("Output buffer size: %zu\n", ary.length);

    // 明确指定输入长度调用加密函数
    err = cipher.encrypt(ary, str.data, str.length);
    if (err != 0) {
        print("Error encrypt: %s\n", err.to_string());
        Process.exit(EXIT_FAILURE);
    }

    string result = Base64.encode(ary);
    print("Encrypted data length: %zu\n", ary.length);
    print("result: %s\n", result);

    cipher.close();
    Process.exit(EXIT_SUCCESS);
}

关键修正点说明

  1. 启用PKCS#7填充:在Cipher.open时添加Cipher.Flag.PKCS7标志,这是CBC模式下加密任意长度明文的必要条件,即使明文长度刚好等于块大小,也会自动添加填充块以保证解密时能正确识别边界。
  2. 指定输入数据长度:调用encrypt时传入str.length,确保GCrypt只加密指定长度的明文数据,避免读取越界或加密不完整。
  3. 分配足够的输出缓冲区:根据AES块大小计算填充后的密文长度,提前分配足够大的缓冲区,避免因空间不足导致加密失败或数据截断。
  4. 显式传递密钥/IV长度:虽然当前密钥/IV长度符合要求,但显式传递长度能避免后续修改字符串时出现长度不匹配的问题,提升代码健壮性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 02:09:12