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

使用OpenSSL的HMAC时触发Access violation错误求助

解决HMAC-SHA512调用中的访问违规错误

你的代码里有两个关键错误直接导致了内存访问违规,我来逐个拆解说明:

1. 数据缓冲区的类型定义错误

你把data定义成了uint8_t* data[]——这是一个指针数组,而非你需要的原始字节数组。当你把这个数组传给HMAC函数时,它会把指针数组里的每个指针值当成原始数据字节处理,直接触发越界访问内存的错误。

正确的定义应该去掉星号,声明为字节数组:

uint8_t data[] = { 0x14, 0xf7, 0xbd, 0x95, 0x57, 0x9a, 0x7e, 0xa1, 0x5c, 0xf7, 0x27, 0x91, 0x0d, 0x61, 0x58, 0x01, 0xa3, 0x12, 0x17, 0x54, 0x0b, 0x2e, 0xb4, 0xc5, 0xb1, 0xeb, 0xab, 0xe0, 0x43, 0x9b, 0x8e, 0x1f, 0x39, 0x7d, 0x85, 0x1a, 0x3a, 0x4b, 0x9c, 0xf4, 0xbf, 0x31, 0x55, 0x72, 0x41, 0xf5, 0xdb, 0xcb, 0xb3, 0xa6, 0xb5, 0xb8, 0x82, 0xe5, 0xef, 0x18, 0x72, 0xa0, 0x59, 0x08, 0x9b, 0xfa, 0x17, 0xa3 };

2. HMAC函数最后一个参数的错误传递

HMAC函数的最后一个参数是unsigned int *len,它是一个指针,用来接收生成的HMAC实际长度(虽然SHA512的HMAC固定为64字节,但函数要求通过指针返回值)。你直接传递(unsigned int)64,相当于把数值64转换成指针,函数会尝试往内存地址0x40(64的十六进制)写入数据——这个低地址属于系统保护内存,必然触发访问违规。

你需要声明一个unsigned int变量,传递它的地址:

unsigned int result_len;
HMAC(EVP_sha512(), key, 12, data, sizeof(data), result, &result_len);

修正后的完整代码

我还优化了几个细节,比如用sizeof(data)代替硬编码的64,用strlen(key)代替硬编码的12,让代码更健壮:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>

int main(int argc, char** argv) {
    // 修正:将指针数组改为字节数组
    uint8_t data[] = { 0x14, 0xf7, 0xbd, 0x95, 0x57, 0x9a, 0x7e, 0xa1, 0x5c, 0xf7, 0x27, 0x91, 0x0d, 0x61, 0x58, 0x01, 0xa3, 0x12, 0x17, 0x54, 0x0b, 0x2e, 0xb4, 0xc5, 0xb1, 0xeb, 0xab, 0xe0, 0x43, 0x9b, 0x8e, 0x1f, 0x39, 0x7d, 0x85, 0x1a, 0x3a, 0x4b, 0x9c, 0xf4, 0xbf, 0x31, 0x55, 0x72, 0x41, 0xf5, 0xdb, 0xcb, 0xb3, 0xa6, 0xb5, 0xb8, 0x82, 0xe5, 0xef, 0x18, 0x72, 0xa0, 0x59, 0x08, 0x9b, 0xfa, 0x17, 0xa3 };
    uint8_t* key = (uint8_t*)"some_rand_pw";
    // 分配SHA512 HMAC所需的64字节缓冲区
    uint8_t* result = malloc(64);
    if (!result) {
        fprintf(stderr, "内存分配失败\n");
        return 1;
    }
    memset(result, 0, 64);
    unsigned int result_len;

    // 修正参数:传递正确的数据缓冲区和长度指针
    HMAC(EVP_sha512(), key, strlen((char*)key), data, sizeof(data), result, &result_len);

    // 可选:输出验证结果
    printf("HMAC-SHA512长度: %u\n", result_len);
    for (int i = 0; i < result_len; i++) {
        printf("%02x", result[i]);
    }
    printf("\n");

    free(result);
    return 0;
}

关于线程安全的说明

你提到的HMAC(..., NULL, NULL)返回静态缓冲区确实是非线程安全的,所以你自己分配独立缓冲区的思路完全正确——只要参数传递正确,这种方式每个线程使用自己的内存空间,不会出现竞争问题,是线程安全的实现方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:03:15