openssl: HMAC算法實現樣例

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章