分享

密钥或者消息的CMAC计算

 wythe 2023-06-19 发布于广东

CMAC主要用于保证消息的完整性和安全性,以及验证密钥的合法性。以下是CMAC常见的应用场景:

1. 数据完整性保护:在网络通信过程中,使用CMAC保护数据的完整性,确保数据在传输过程中不被篡改或破坏。

2. 消息认证:使用CMAC对消息进行认证,验证消息是否是由合法的发送者发送,并防止被篡改。

3. 密钥管理:在密钥的生成和分配过程中,使用CMAC来校验密钥的合法性,确保生成的密钥符合安全要求。

4. 应用程序安全:在应用程序中使用CMAC对数据进行加密和认证处理,以保证数据的安全性和私密性。

总的来说,CMAC是一种非常实用的消息认证码,能够在多种应用中提供数据安全性和完整性的保护。

下面我通过一个两个荔枝,分别来说明CMAC的计算

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/cmac.h>

unsigned char* ssl_cmac(const unsigned char* key, const unsigned char* message, size_t message_len ,int *out_cmac_len) {
    CMAC_CTX* ctx = CMAC_CTX_new();
    unsigned char* mac = NULL;
    size_t mac_len = 0;
    int rc = 0;
    if (ctx == NULL) {
        printf("Failed to allocate memory for CMAC context\n");
        return NULL;
    }
    rc = CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL);
    if (rc != 1) {
        printf("Failed to initialize CMAC\n");
        goto cleanup;
    }
    rc = CMAC_Update(ctx, message, message_len);
    if (rc != 1) {
        printf("Failed to update CMAC\n");
        goto cleanup;
    }
	
    mac = malloc(mac_len * sizeof(unsigned char));
    if (mac == NULL) {
        printf("Failed to allocate memory for MAC\n");
        goto cleanup;
    }
	memset(mac , 0 , mac_len);
	
    rc = CMAC_Final(ctx, mac, &mac_len);
    if (rc != 1) {
        printf("Failed to compute CMAC\n");
        free(mac);
        mac = NULL;
        goto cleanup;
    }
	*out_cmac_len = mac_len;
cleanup:
    if (ctx != NULL) {
        CMAC_CTX_free(ctx);
        ctx = NULL;
    }
    return mac;
}



//计算密钥checkvalue CMAC
unsigned char* key_check_value(unsigned char* key, size_t key_len) {
    unsigned char* mac = NULL;
    unsigned char message[16] = {0};
	int rc = 0;
	//unsigned char * message = malloc(key_len);
	//memset(message , 0 , key_len);
    CMAC_CTX* ctx = CMAC_CTX_new();
    if (ctx == NULL) {
        printf("Failed to allocate memory for CMAC context\n");
        return NULL;
    }
	if(key_len == 16)
		rc = CMAC_Init(ctx, key, key_len, EVP_aes_128_cbc(), NULL);
	else
		rc = CMAC_Init(ctx, key, key_len, EVP_aes_192_cbc(), NULL);
    if (rc != 1) {
        printf("Failed to initialize CMAC\n");
        goto cleanup;
    }
    rc = CMAC_Update(ctx, message, sizeof(message));
    if (rc != 1) {
        printf("Failed to update CMAC\n");
        goto cleanup;
    }
    mac = malloc(EVP_MAX_BLOCK_LENGTH);
    if (mac == NULL) {
        printf("Failed to allocate memory for MAC\n");
        goto cleanup;
    }
    size_t mac_size = 0;
    rc = CMAC_Final(ctx, mac, &mac_size);
    if (rc != 1) {
        printf("Failed to compute CMAC\n");
        free(mac);
        mac = NULL;
        goto cleanup;
    }
    if (mac_size < 16) {
        printf("Invalid CMAC size\n");
        free(mac);
        mac = NULL;
        goto cleanup;
    }
    mac[15] &= 0x7F; // Clear the last bit to get the check value
cleanup:
    if (ctx != NULL) {
        CMAC_CTX_free(ctx);
        ctx = NULL;
    }
    return mac;
}

int main(int argc, char ** argv)
{
	char key[]={10, 11 , 12 , 13 ,14 ,15, 16, 17, 18, 19, 20, 21, 22 , 23 ,24, 25};
	char msg[16] = {0};
	int  mac_len = 16;
	int i = 0;
	unsigned char *cmacs = NULL;
	//unsigned char *cmacs = ssl_cmac(key, msg, strlen(msg)+1 ,&mac_len);
	//unsigned char *cmacs = cmac(key, msg, strlen(msg)+1);
	//printf("cmac ssl_cmac calc cmacs = %p\n",cmacs);
	cmacs = key_check_value(key, sizeof(key));
	printf("cmac key_check_value calc\n");
	
	for(i= 0;i< mac_len; i++)
	{
		//printf("i=%d %02X \n", i, (unsigned char )cmacs[i]);
		printf("%02X ", (unsigned char )cmacs[i]);
	}
	printf("\n");
	if(cmacs!=NULL)
	{
		cmacs = NULL;
		free(cmacs);
	}
	
	printf("cmac ssl_cmac calc\n");
	cmacs = ssl_cmac(key, msg, 16 ,&mac_len);
	
	printf("cmac ssl_cmac calc cmacs = %p\n",cmacs);
	
	for(i=0;i< mac_len; i++)
	{
		//printf("i=%d %02X \n", i, (unsigned char )cmacs[i]);
		printf("%02X ", (unsigned char )cmacs[i]);
	}
	
	printf("\n");
	if(cmacs!=NULL)
		free(cmacs);
	
}

以上就是计算密钥key的,CMAC作为key的密钥校验值

xxxx@XXXX:~/linux-sys/tls$ ./cmac
cmac ssl_cmac calc cmacs = (nil)
cmac key_check_value calc
C4 4E 68 F0 DA 50 12 81 7D 1B 40 D6 5D D4 71 49 
cmac ssl_cmac calc
cmac ssl_cmac calc cmacs = 0x19936a0
C4 4E 68 F0 DA 50 12 81 7D 1B 40 D6 5D D4 71 C9 
xxxx@XXXX:~/linux-sys/tls$

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多