当前位置:   article > 正文

CMAC--基于分组密码的消息认证码的实现及其应用_cmac_ctx_new

cmac_ctx_new

前言

CMAC(基于分组加密的消息认证码),一般用作消息的签名。与HMAC相同的是都需要一把秘钥来加密内容得到MAC,只是MAC的产生方法不同,一个是用hash算法,一个是用分组加密算法。两种方法具体原理参见:

https://blog.csdn.net/kkxgx/article/details/10307663

实际上,CMAC-128的计算结果是128位的,而AES的密钥也是128位的,所以利用这个特性,我们可以将一个AES密钥经过CMAC生产出多个输出,这些输出可以用来做不同用途的密钥,所以,当我们一个模块需要多个密钥参与时,又不想利用用户输入过个密钥,那么这是个很好的解决办法,模块内部实现密钥的派生,我们称这个过程叫密钥的推算。

Openssl实现CMAC生成

  1. 1 #include <openssl/cmac.h>
  2. 2 #include <openssl/evp.h>
  3. 3 #include <stdio.h>
  4. 4 #include <stdlib.h>
  5. 5 #include <string.h>
  6. 6 int main(int arg, char *argv[]){
  7. 7 char key[17]="1234567891234567";
  8. 8 const EVP_CIPHER* cipher = EVP_aes_128_cbc();
  9. 9 CMAC_CTX* cmac_ctx = CMAC_CTX_new();
  10. 10 if (!cmac_ctx){
  11. 11 printf("create error!\n");
  12. 12 return -1;
  13. 13 }
  14. 14 if (!CMAC_Init(cmac_ctx,key,16,cipher,0)){
  15. 15 CMAC_CTX_free(cmac_ctx);
  16. 16 printf("init error!\n");
  17. 17 return -1;
  18. 18 }
  19. 19 char *meg = "adadffdfsdif2345";
  20. 20 if(!CMAC_Update(cmac_ctx,meg,strlen(meg))){
  21. 21 CMAC_CTX_free(cmac_ctx);
  22. 22 printf("update error!\n");
  23. 23 return -1;
  24. 24 }
  25. 25 size_t reslen;
  26. 26 uint8_t res[128];
  27. 27 if (!CMAC_Final(cmac_ctx, res, &reslen)) {
  28. 28 printf("[DeriveKey(): OEMCrypto_ERROR_CMAC_FAILURE]\n");
  29. 29 return -1;
  30. 30 }
  31. 31 printf("derive key len[%ld]data:\n",reslen);
  32. 32 for(int i = 0; i < reslen; i++){
  33. 33 printf("%x_",res[i]);
  34. 34 }
  35. 35 printf("\n");
  36. 36 CMAC_CTX_free(cmac_ctx);
  37. 37 return 0;
  38. 38
  39. 39 }

运行结果:

jilinglin@ubuntu:~/SourceCode/OpensslProject/CMAC$ ./cmac 
derive key len[16]data:
1_3e_6c_3e_33_48_1e_64_4b_e3_94_66_56_2f_ea_93_
 

密钥推算(派生)

对于秘钥的推算,我们可以采用这种方法:将一段内容固定,然后在其后分别添加计数值,这样生成的结果就会随着计数值得不同而不同。在通信双方只需传递固定的那段内容,双方都可以推算出相同的秘钥。

  1. 1 #include <openssl/cmac.h>
  2. 2 #include <openssl/evp.h>
  3. 3 #include <stdio.h>
  4. 4 #include <stdlib.h>
  5. 5 #include <string.h>
  6. 6 int derivekey(char *msg) {
  7. 7 char key[17]="1234567891234567";
  8. 8 const EVP_CIPHER* cipher = EVP_aes_128_cbc();
  9. 9 CMAC_CTX* cmac_ctx = CMAC_CTX_new();
  10. 10 if (!cmac_ctx){
  11. 11 printf("create error!\n");
  12. 12 return -1;
  13. 13 }
  14. 14 if (!CMAC_Init(cmac_ctx,key,16,cipher,0)){
  15. 15 CMAC_CTX_free(cmac_ctx);
  16. 16 printf("init error!\n");
  17. 17 return -1;
  18. 18 }
  19. 19 //char *meg = "adadffdfsdif2345";
  20. 20 if(!CMAC_Update(cmac_ctx,msg,strlen(msg))){
  21. 21 CMAC_CTX_free(cmac_ctx);
  22. 22 printf("update error!\n");
  23. 23 return -1;
  24. 24 }
  25. 25 size_t reslen;
  26. 26 uint8_t res[128];
  27. 27 if (!CMAC_Final(cmac_ctx, res, &reslen)) {
  28. 28 printf("[DeriveKey(): OEMCrypto_ERROR_CMAC_FAILURE]\n");
  29. 29 return -1;
  30. 30 }
  31. 31 printf("derive key len[%ld]data:\n",reslen);
  32. 32 for(int i = 0; i < reslen; i++){
  33. 33 printf("%x_",res[i]);
  34. 34 }
  35. 35 printf("\n");
  36. 36 CMAC_CTX_free(cmac_ctx);
  37. 37 return 0;
  38. 38 }
  39. 39
  40. 40 int main(int argc,char *argv[]){
  41. 41 char *meg_0 = "adadffdfsdif2345";
  42. 42 unsigned int string_len = strlen(meg_0);
  43. 43 printf("strlen =[%d]\n",string_len);
  44. 44 char *msg = malloc(string_len+2);
  45. 45 memcpy(msg,meg_0,string_len);
  46. 46 for(int i = 0; i<5; i++ ){
  47. 47 printf("key num[%d] ",i);
  48. 48 *(msg+string_len)= i;
  49. 49 *(msg+string_len+1)= '\0';
  50. 50 derivekey(msg);
  51. 51 }
  52. 52 free(msg);
  53. 53 return 0;
  54. 54 }

运行结果:

strlen =[16]
key num[0] derive key len[16]data:
1_3e_6c_3e_33_48_1e_64_4b_e3_94_66_56_2f_ea_93_
key num[1] derive key len[16]data:
20_75_a8_67_c7_d4_f5_5b_3_ef_cc_cb_a0_1c_11_be_
key num[2] derive key len[16]data:
5c_c4_14_f4_c3_4d_a6_69_fd_79_a2_c8_8e_4a_4f_cf_
key num[3] derive key len[16]data:
cf_c3_19_e6_8e_ea_c3_c6_c0_34_20_7e_95_7d_a9_32_
key num[4] derive key len[16]data:
42_af_a1_c0_2b_f6_1_d9_4b_9c_29_ee_b1_86_65_c_
 

自此,key的推算就完成了,例子只推算了5个key,固定消息的长度可以自己设置,输出结果都是128位(16字节)。

两个例子的编译方法:gcc -o cmac cmac.c -lcrypto -lssl

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/51960
推荐阅读
相关标签
  

闽ICP备14008679号