openssl: HMAC算法實現樣例
算法實現樣例:
- HMAC-SHA1
- HMAC-SHA224
- HMAC-SHA256
- HMAC-SHA384
- HMAC-SHA512
- HMAC-MD5
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
void hmac(const char *algorithm, const char *msg, size_t msgLen, const char *key, size_t keyLen) {
if (algorithm == NULL || msg == NULL || key == NULL) {
printf("%s %d %s: parameter error\n", __FILE__, __LINE__, __func__);
exit(1);
}
const EVP_MD *md = EVP_get_digestbyname(algorithm);
if (md == NULL) {
printf("%s %d %s: unknown message digest: %s\n", __FILE__, __LINE__, __func__, algorithm);
exit(1);
}
unsigned char md_value[EVP_MAX_MD_SIZE] = "";
unsigned int md_len = 0;
#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, key, keyLen, md, NULL);
HMAC_Update(&ctx, msg, msgLen);
HMAC_Final(&ctx, md_value, &md_len);
HMAC_CTX_cleanup(&ctx);
#else
HMAC_CTX *ctx;
ctx = HMAC_CTX_new();
HMAC_Init_ex(ctx, key, keyLen, md, NULL);
HMAC_Update(ctx, msg, msgLen);
HMAC_Final(ctx, md_value, &md_len);
HMAC_CTX_free(ctx);
#endif
static const char bin2chars[] = "0123456789abcdef";
char *result = (char *)malloc(md_len*2+1);
result[md_len*2] = 0;
for (unsigned int i = 0; i < md_len; i++) {
result[i*2] = bin2chars[md_value[i] >> 4];
result[i*2+1] = bin2chars[md_value[i] & 0x0f];
}
printf("%s %d %s: %s\t\t%s\n", __FILE__, __LINE__, __func__, algorithm, result);
free(result);
}
int main() {
OpenSSL_add_all_digests();
const char *msg = "0123456789ABCDEF";
const char *key = "test1280";
/* msg和key都是可讀明文,不包含0x00,因此可以用strlen */
/* 考慮到通用情況,不應該使用strlen,因爲原數據可能包含0x00 */
hmac("SHA1", msg, strlen(msg), key, strlen(key));
hmac("SHA224", msg, strlen(msg), key, strlen(key));
hmac("SHA256", msg, strlen(msg), key, strlen(key));
hmac("SHA384", msg, strlen(msg), key, strlen(key));
hmac("SHA512", msg, strlen(msg), key, strlen(key));
hmac("MD5", msg, strlen(msg), key, strlen(key));
/* Call this once before exit. */
EVP_cleanup();
return 0;
}
編譯 & 運行:
[test1280@localhost ~]$ gcc -o main main.c -lssl -lcrypto -g
[test1280@localhost ~]$ ./main
main.c 46 hmac: SHA1 e665c280cf27dacd1f1b6b053cb307f32ee32fd0
main.c 46 hmac: SHA224 e72c400c02606686be2a8f7b75dd30234944ba55d7ac60953e848609
main.c 46 hmac: SHA256 b75ddc670bb8c75296d3207bfa8549df81ba3ef33500593c9d644a03dbcc1e0d
main.c 46 hmac: SHA384 809f4653a5cc87ac82eaf3b95d7351406034198c13353b6c6cab8878c3ea2f1c607d5593b635e2d9718e95ba900f2939
main.c 46 hmac: SHA512 44f986af4ca102bfa133e7135994173e120399078e4fdbf2363c4ac975cc3ff67cbe235c7e3667a6120827118dc3ac8e54c949d7f6fdacc704cdf86b1c13a530
main.c 46 hmac: MD5 5539dccd74dffdb0c671cc88c930bc25