【问题标题】:Generate HMAC SHA256 in C在 C 中生成 HMAC SHA256
【发布时间】:2020-06-30 14:15:03
【问题描述】:

我正在 java 应用程序中创建 HMAC 摘要并希望将其验证到 C 程序中。我有一个十六进制格式的硬编码密钥。

我在尝试用 C 计算 HmacSHA256 时遇到分段错误。我无法弄清楚我在搞砸什么。

java程序

        byte[] decodedKey = hexStringToByteArray("d44d4435c5eea8791456f2e20d7e176a");
            SecretKey key = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES"); 
       
        try {
            Mac mac = Mac.getInstance("HmacSHA256");    //Creating a Mac object
            mac.init(key);        //Initializing the Mac object
            byte[] bytes = challenge.getBytes();   
            byte[] macResult = mac.doFinal(bytes);
            return macResult;
        } catch (NoSuchAlgorithmException e) {
            System.out.println("Not valid algorithm"+ e);
        } catch (InvalidKeyException e) {
            System.out.println("Invalid key"+ e);
        }

C 程序

    const char* key = hexstr_to_char("d44d4435c5eea8791456f2e20d7e176a");
    unsigned char *result;
    unsigned int* resultlen;
    hmac_sha256(key, strlen(key),
                               challenge, strlen("d44d4435c5eea8791456f2e20d7e176a"),
                               result, resultlen);



unsigned char* hmac_sha256(const void *key, int keylen,
                           const unsigned char *data, int datalen,
                           unsigned char *result, unsigned int* resultlen)
{
    return HMAC(EVP_sha256(), key, keylen, data, datalen, result, resultlen);
}

unsigned char* hexstr_to_char(const char* hexstr)
{
    size_t len = strlen(hexstr);
    if (len % 2 != 0)
        return NULL;
    size_t final_len = len / 2;
    unsigned char* chrs = (unsigned char*)malloc((final_len+1) * sizeof(*chrs));
    for (size_t i=0, j=0; j<final_len; i+=2, j++)
        chrs[j] = (hexstr[i] % 32 + 9) % 25 * 16 + (hexstr[i+1] % 32 + 9) % 25;
    chrs[final_len] = '\0';
    return chrs;
}

【问题讨论】:

  • 使用调试器。它将准确地告诉您哪一行代码触发了段错误,这是您应该已经知道并应该在此处分享的最少信息量。
  • 提示:resultresultlen 指向哪里?
  • 你需要为你的结果分配一个缓冲区,而不仅仅是传入一个未初始化的指针。

标签: c openssl hmac


【解决方案1】:

如果您更仔细地阅读 HMAC() 的文档,您会发现有几种方法可以调用该方法来确定输出缓冲区的大小,或者让它返回一个静态数组缓冲区。

您可以为结果传递 NULL 并通过第一次调用获取长度,然后分配结果缓冲区并再次调用。

或者您可以将 NULL 传递给结果缓冲区,它会返回一个静态数组缓冲区(您不拥有该缓冲区),但它被记录为不是线程安全的。

最简单的方法可能是依靠 EVP_MAX_MD_SIZE 静态声明您的缓冲区。您还应该将长度变量声明为 int 而不是 int*,并使用 & 操作传递其地址 - 这是非常基本的 C。

试试这个:

unsigned int resultlen = 0;
unsigned char resultbuf[EVP_MAX_MD_SIZE];
hmac_sha256(key, strlen(key), challenge, strlen("d44d4435c5eea8791456f2e20d7e176a"),
                         resultbuf, &resultlen);

文档: https://www.openssl.org/docs/man1.1.1/man3/HMAC.html

那里有很多 C 语言教程。

【讨论】:

    猜你喜欢
    • 2016-10-25
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    • 2022-01-21
    • 2016-08-20
    相关资源
    最近更新 更多