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$ |
|