HMAC運算利用哈希算法,以一個密鑰和一個消息為輸入,生成一個消息摘要作為輸出。HMACSHA1 接受任何大小的密鑰,並產生長度為 160 位(20字節)的哈希序列。
linux平台代碼:
依賴openssl庫,先安裝openssl依賴庫:
yum install openssl openssl-devel -y
檢查/usr/local/下是否有openssl文件夾
加密C代碼:
test.c
#include <stdio.h>
#include <string.h>
#include <openssl/hmac.h>
int main(int argc,void **argv) {
//key value
const char key[] = "745s295z8lv458ll46w2467ta460562n";
//data in hex, /or you can init with text
unsigned char data[] = {
0x00,0x01,0x00,0x48,0x21,0x12,0xa4,0x42,0x78,0x2b,0x66,0x6b,0x32,0x34,0x30,0x6b
,0x4e,0x51,0x6a,0x56,0x00,0x06,0x00,0x0d,0x36,0x37,0x76,0x32,0x37,0x30,0x37,0x35
,0x3a,0x31,0x33,0x42,0x5a,0x00,0x00,0x00,0xc0,0x57,0x00,0x04,0x00,0x02,0x00,0x00
,0x80,0x2a,0x00,0x08,0x70,0xfb,0xe5,0x05,0x91,0xbf,0x83,0x3c,0x00,0x24,0x00,0x04
,0x6e,0x7e,0x1e,0xff
};
unsigned char result[20] = {0};
int resultlen = 20;
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
// Using sha1 hash engine here.
// You may use other hash engines. e.g EVP_md5(), EVP_sha224, EVP_sha512, etc
HMAC_Init_ex(&ctx, key, strlen(key), EVP_sha1(), NULL);
HMAC_Update(&ctx, (unsigned char*)&data, sizeof(data));
HMAC_Final(&ctx, result, &resultlen);
HMAC_CTX_cleanup(&ctx);
//print the result in hex format
for (int i = 0; i < resultlen; i++)
printf("%02x", result[i]);
printf("\n");
return 0;
}
/* 1.1.1m版本 HMAC_CTX *ctx = HMAC_CTX_new(); HMAC_Init_ex(ctx, passwd, passwdlen, EVP_sha1(), NULL); HMAC_Update(ctx, data, datalen); HMAC_Final(ctx, dest, destlen); HMAC_CTX_free(ctx); */
linux使用命令gcc編譯,需要依賴libcrypto,編譯命令如下:
gcc -o test test.c -lssl -lcrypto
編譯后執行./test即可看到結果:
c7c49a60946fa024e5f6212ec63814fe2e76b26d
結果是否正確可以根據系列03或者其中的網址進行二次校驗
windows平台代碼:
#include <stdio.h>
#include <openssl/ossl_typ.h>
#include <openssl/hmac.h>
#include <string.h>
void hmac_sha1(char* passwd, int passwdlen, unsigned char* data, short datalen, unsigned char* dest, unsigned int *destlen) {
//use hmac sha1 to encode data with remote passwd.
HMAC_CTX *ctx = HMAC_CTX_new();
HMAC_Init_ex(ctx, passwd, passwdlen, EVP_sha1(), NULL);
HMAC_Update(ctx, data, datalen);
HMAC_Final(ctx, dest, destlen);
HMAC_CTX_free(ctx);
}
int main(int argc, char **argv) {
unsigned char data[] = {
0x00,0x01,0x00,0x48,0x21,0x12,0xa4,0x42,0x78,0x2b,0x66,0x6b,0x32,0x34,0x30,0x6b
,0x4e,0x51,0x6a,0x56,0x00,0x06,0x00,0x0d,0x36,0x37,0x76,0x32,0x37,0x30,0x37,0x35
,0x3a,0x31,0x33,0x42,0x5a,0x00,0x00,0x00,0xc0,0x57,0x00,0x04,0x00,0x02,0x00,0x00
,0x80,0x2a,0x00,0x08,0x70,0xfb,0xe5,0x05,0x91,0xbf,0x83,0x3c,0x00,0x24,0x00,0x04
,0x6e,0x7e,0x1e,0xff };
int datalen = sizeof(data);
char passwd[] = "745s295z8lv458ll46w2467ta460562n";
int passwdlen = strlen(passwd);
unsigned char result[20] = { 0 };
unsigned int resultlen = 0;
hmac_sha1(passwd, passwdlen, data, datalen, result, &resultlen);
for (int i = 0; i < resultlen; i++)
printf("%02x", result[i]);
printf("\n");
return 0;
}
windows需要安裝openssl,需要編譯x86時選擇對應32位版本的openssl安裝,否則會出錯
將openssl的include和lib庫路徑填入工程,並添加libcrypto.lib庫,編譯即可。運行結果如下:

