openssl3.2 - 官方demo学习 - mac - cmac-aes256.c

本文详细介绍了如何在OpenSSL3.2中使用EVP_MAC方法,特别是通过AES-256-CBC算法计算和验证消息认证码(MAC)。演示了加密密钥的使用、明文处理以及MAC生成与预期值的比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

openssl3.2 - 官方demo学习 - mac - cmac-aes256.c

概述

指定加密算法(e.g. AES-256-CBC), 对明文生成MAC数据

笔记

/*!
\file cmac-aes256.c
\note openssl3.2 - 官方demo学习 - mac - cmac-aes256.c
指定加密算法(e.g. AES-256-CBC), 对明文生成MAC数据
*/

/*-
 * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

 /*
  * Example of using EVP_MAC_ methods to calculate
  * a CMAC of static buffers
  */

#include <string.h>
#include <stdio.h>
#include <openssl/crypto.h>
#include <openssl/core_names.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/cmac.h>
#include <openssl/params.h>

#include "my_openSSL_lib.h"

  /*
   * Hard coding the key into an application is very bad.
   * It is done here solely for educational purposes.
   */
static unsigned char key[] = {
	0x6c, 0xde, 0x14, 0xf5, 0xd5, 0x2a, 0x4a, 0xdf,
	0x12, 0x39, 0x1e, 0xbf, 0x36, 0xf9, 0x6a, 0x46,
	0x48, 0xd0, 0xb6, 0x51, 0x89, 0xfc, 0x24, 0x85,
	0xa8, 0x8d, 0xdf, 0x7e, 0x80, 0x14, 0xc8, 0xce,
};

static const unsigned char data[] =
"To be, or not to be, that is the question,\n"
"Whether tis nobler in the minde to suffer\n"
"The ſlings and arrowes of outragious fortune,\n"
"Or to take Armes again in a sea of troubles,\n"
"And by opposing, end them, to die to sleep;\n"
"No more, and by a sleep, to say we end\n"
"The heart-ache, and the thousand natural shocks\n"
"That flesh is heir to? tis a consumation\n"
"Devoutly to be wished. To die to sleep,\n"
"To sleepe, perchance to dreame, Aye, there's the rub,\n"
"For in that sleep of death what dreams may come\n"
"When we haue shuffled off this mortal coil\n"
"Must give us pause. There's the respect\n"
"That makes calamity of so long life:\n"
"For who would bear the Ships and Scorns of time,\n"
"The oppressor's wrong, the proud man's Contumely,\n"
"The pangs of dispised love, the Law's delay,\n"
;

/* The known value of the CMAC/AES256 MAC of the above soliloqy */
static const unsigned char expected_output[] = {
	0x67, 0x92, 0x32, 0x23, 0x50, 0x3d, 0xc5, 0xba,
	0x78, 0xd4, 0x6d, 0x63, 0xf2, 0x2b, 0xe9, 0x56,
};

/*
 * A property query used for selecting the MAC implementation.
 */
static const char* propq = NULL;

int main(void)
{
	int ret = EXIT_FAILURE;
	OSSL_LIB_CTX* _ossl_lib_ctx = NULL;
	EVP_MAC* _evp_mac = NULL;
	EVP_MAC_CTX* _evp_mac_ctx = NULL;
	unsigned char* out = NULL;
	size_t out_len = 0;
	OSSL_PARAM _ossl_param_ary[4], * p_ossl_param = _ossl_param_ary;
	char cipher_name[] = "AES-256-CBC";

	_ossl_lib_ctx = OSSL_LIB_CTX_new();
	if (_ossl_lib_ctx == NULL) {
		fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n");
		goto end;
	}

	/* Fetch the CMAC implementation */
	_evp_mac = EVP_MAC_fetch(_ossl_lib_ctx, "CMAC", propq);
	if (_evp_mac == NULL) {
		fprintf(stderr, "EVP_MAC_fetch() returned NULL\n");
		goto end;
	}

	/* Create a context for the CMAC operation */
	_evp_mac_ctx = EVP_MAC_CTX_new(_evp_mac);
	if (_evp_mac_ctx == NULL) {
		fprintf(stderr, "EVP_MAC_CTX_new() returned NULL\n");
		goto end;
	}

	/* The underlying cipher to be used */
	*p_ossl_param++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name,
		sizeof(cipher_name));
	*p_ossl_param = OSSL_PARAM_construct_end();

	/* Initialise the CMAC operation */
	if (!EVP_MAC_init(_evp_mac_ctx, key, sizeof(key), _ossl_param_ary)) {
		fprintf(stderr, "EVP_MAC_init() failed\n");
		goto end;
	}

	/* Make one or more calls to process the data to be authenticated */
	if (!EVP_MAC_update(_evp_mac_ctx, data, sizeof(data))) {
		fprintf(stderr, "EVP_MAC_update() failed\n");
		goto end;
	}

	/* Make a call to the final with a NULL buffer to get the length of the MAC */
	if (!EVP_MAC_final(_evp_mac_ctx, NULL, &out_len, 0)) {
		fprintf(stderr, "EVP_MAC_final() failed\n");
		goto end;
	}
	out = OPENSSL_malloc(out_len);
	if (out == NULL) {
		fprintf(stderr, "malloc failed\n");
		goto end;
	}
	/* Make one call to the final to get the MAC */
	if (!EVP_MAC_final(_evp_mac_ctx, out, &out_len, out_len)) {
		fprintf(stderr, "EVP_MAC_final() failed\n");
		goto end;
	}

	printf("Generated MAC:\n");
	BIO_dump_indent_fp(stdout, out, (int)out_len, 2);
	putchar('\n');

	if (out_len != (size_t)sizeof(expected_output)) {
		fprintf(stderr, "Generated MAC has an unexpected length\n");
		goto end;
	}

	if (CRYPTO_memcmp(expected_output, out, sizeof(expected_output)) != 0) {
		fprintf(stderr, "Generated MAC does not match expected value\n");
		goto end;
	}

	ret = EXIT_SUCCESS;
end:
	if (ret != EXIT_SUCCESS)
		ERR_print_errors_fp(stderr);
	/* OpenSSL free functions will ignore NULL arguments */
	OPENSSL_free(out);
	EVP_MAC_CTX_free(_evp_mac_ctx);
	EVP_MAC_free(_evp_mac);
	OSSL_LIB_CTX_free(_ossl_lib_ctx);
	return ret;
}

END

详细介绍了AES-CMAC的算法的原理与实现,附有C语言写的样例程序。 以下是原文的introduction: The National Institute of Standards and Technology (NIST) has recently specified the Cipher-based Message Authentication Code(CMAC). CMAC [NIST-CMAC] is a keyed hash function that is based on a symmetric key block cipher, such as the Advanced Encryption Standard [NIST-AES]. CMAC is equivalent to the One-Key CBC MAC1 (OMAC1) submitted by Iwata and Kurosawa [OMAC1a, OMAC1b]. OMAC1 is an improvement of the eXtended Cipher Block Chaining mode (XCBC) submitted by Black and Rogaway [XCBCa, XCBCb], which itself is an improvement of the basic Cipher Block Chaining-Message Authentication Code (CBC-MAC). XCBC efficiently addresses the security deficiencies of CBC-MAC, and OMAC1 efficiently reduces the key size of XCBC. AES-CMAC provides stronger assurance of data integrity than a checksum or an error-detecting code. The verification of a checksum or an error-detecting code detects only accidental modifications of the data, while CMAC is designed to detect intentional, unauthorized modifications of the data, as well as accidental modifications. AES-CMAC achieves a security goal similar to that of HMAC [RFC-HMAC]. Since AES-CMAC is based on a symmetric key block cipher, AES, and HMAC is based on a hash function, such as SHA-1, AES-CMAC is appropriate for information systems in which AES is more readily available than a hash function. This memo specifies the authentication algorithm based on CMAC with AES-128. This new authentication algorithm is named AES-CMAC.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值