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

C++ Argon2id哈希生成异常:无法将HEX格式结果转换为标准Argon2id哈希字符串

C++ Argon2id哈希生成异常:无法将HEX格式结果转换为标准Argon2id哈希字符串

看起来你现在卡在了“把生成的Argon2id HEX哈希转换成标准格式字符串”这一步对吧?我帮你拆解下问题核心,再给你修正后的代码方案。

首先得明确:标准Argon2id哈希字符串是用$分隔的结构化组合,它的格式是这样的:

$argon2id$v=19$m=16,t=2,p=1$[URL安全Base64编码的salt]$[URL安全Base64编码的哈希值]

你现在拿到的是HEX格式的哈希,这只是其中的一部分,还需要把参数、salt的Base64编码版本和它拼在一起才行。而且这里有几个容易踩坑的点:

  • 标准格式里用的是URL安全的Base64编码(替换+为-、/为_,且无填充字符=),不是普通Base64,也不是HEX
  • Salt不能直接用明文,必须转成Base64编码
  • 参数顺序必须是m=内存成本,t=迭代次数,p=并行度,不能乱序
  • 版本号v=19对应的是Argon2的ARGON2_VERSION_13版本,这是当前的稳定标准

接下来看你的代码问题:你应该是只生成了哈希的HEX值,没有完成后续的编码和拼接步骤。下面是修正后的完整代码,包含了从生成哈希到组装成标准格式的全流程:

#include <argon2.h>
#include <string.h>
#include <vector>
#include <algorithm>
#include <string>

// 辅助函数:实现URL安全的Base64编码(无填充字符)
std::string base64_url_encode(const uint8_t* data, size_t len) {
    const std::string base64_chars = 
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz"
        "0123456789-_";
    
    std::string result;
    int i = 0;
    int j = 0;
    uint8_t char_array_3[3];
    uint8_t char_array_4[4];

    while (len--) {
        char_array_3[i++] = *(data++);
        if (i == 3) {
            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
            char_array_4[3] = char_array_3[2] & 0x3f;

            for(i = 0; (i <4) ; i++)
                result += base64_chars[char_array_4[i]];
            i = 0;
        }
    }

    if (i) {
        for(j = i; j < 3; j++)
            char_array_3[j] = '\0';

        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;

        for (j = 0; (j < i + 1); j++)
            result += base64_chars[char_array_4[j]];
    }

    // 确保移除所有填充字符(这里我们本身就没生成,但保险起见)
    result.erase(std::remove(result.begin(), result.end(), '='), result.end());
    return result;
}

std::string DBManager::Argon2PasswordHash(const char* password) {
    // 你指定的参数配置
    const uint32_t t_cost = 2;         // 迭代次数
    const uint32_t m_cost = 16;        // 内存成本(单位:KB)
    const uint32_t parallelism = 1;    // 并行度
    const uint32_t hash_len = 64;      // 哈希长度
    const uint32_t argon2_version = ARGON2_VERSION_13; // 对应v=19

    // Salt配置
    uint8_t salt[] = "MYSALTISCOOL";
    const uint32_t salt_len = strlen(reinterpret_cast<char*>(salt));

    // 分配内存存储原始哈希字节数组
    std::vector<uint8_t> hash_result(hash_len);

    // 调用Argon2id生成原始哈希(直接生成字节数组,避免先转HEX的额外步骤)
    int ret = argon2id_hash_raw(
        t_cost, m_cost, parallelism,
        password, strlen(password),
        salt, salt_len,
        hash_result.data(), hash_len,
        nullptr, 0,
        argon2_version
    );

    // 处理哈希生成错误
    if (ret != ARGON2_OK) {
        // 这里可以根据需要返回错误标识或抛出异常
        return "";
    }

    // 对salt和哈希结果进行URL安全的Base64编码
    std::string salt_b64 = base64_url_encode(salt, salt_len);
    std::string hash_b64 = base64_url_encode(hash_result.data(), hash_len);

    // 按照标准格式拼接所有部分
    std::string final_hash = "$argon2id$v=" + std::to_string(argon2_version) +
                            "$m=" + std::to_string(m_cost) + ",t=" + std::to_string(t_cost) + ",p=" + std::to_string(parallelism) +
                            "$" + salt_b64 +
                            "$" + hash_b64;

    return final_hash;
}

几个关键的修正点说明:

  1. 改用argon2id_hash_raw直接生成哈希字节数组,跳过了转HEX的步骤,既高效又方便后续转Base64
  2. 实现了符合Argon2标准的URL安全Base64编码,确保生成的字符串和目标格式一致
  3. 严格按照标准格式拼接参数、salt编码、哈希编码,参数顺序完全匹配要求
  4. 明确指定了Argon2版本为ARGON2_VERSION_13,对应格式里的v=19

你可以测试下这段代码,只要你的密码和参数完全匹配,生成的哈希字符串应该就和你给出的目标示例一致了。

备注:内容来源于stack exchange,提问作者André Santos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 11:13:15