知识点归纳
最有收获的内容
原来除了HMAC,还有基于分组密码的CBC-MAC、CMAC和GMAC
CBC-MAC是一种将分组密码转换为MAC的经典方法。密钥K被用作分组密码的密钥:CBC-MAC所采用的方法是对消息也用CBC模式进行加密,而只保留密文的最后一个 分组,其余全部丢弃。
GMAC的工作原理完全不同于CBC-MAC、CMAC以及HMAC。GMAC的认证函数有三个输入:密钥、待认证的消息、瞬时值,该瞬时值只使用一次。CBC-MAC , CMAC和 HMAC的算法中都没有使用瞬时值作为输入。如果使用密钥和瞬时值对消息进行MAC运算,接收者也需知道这个瞬时值,所以需要发送者通过某种方式将瞬时值发送给接收者。瞬时值也可以是隐含的,如发送者和接收者都维护的包计数器。
建议选择HMAC-SHA-256
遇到的问题与解决过程
不是很明白Horton原则。
Horton原则:消息认证是认证消息的含义,而不是消息本身。
MAC仅仅对字节串进行认证,而Alice和Bob想对具有特定含义的消息进行认证,字节串(发送的字节)和字节串的含义(对消息的理解)这两者的差别是很重要的。
但是所有的消息到底层都是字节串啊,都要被MAC保护啊,字节串的含义不是应该由上层应用去解释吗?
多读了几遍,发现他说的意思可能是,如果有选择得用MAC去保护消息,那就不仅仅要保护消息的数据部分,还要保护“数据怎么解释的部分”,如果数据的解释方法也需要被当做数据传输的话。
实践内容
使用OpenSSL实现计算文件的SM3哈希值
顺带支持MD5和SHA-2系列
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#define SM3_DIGEST_LENGTH 32
#define MAX_DIGEST_LENGTH 64
int SM3_digest(const char *algorithms,const char *infile,const char *outfile){
FILE *fp1 = fopen(infile,"rb");
FILE *fp2 = fopen(outfile,"wb");
if(fp1==NULL || fp2==NULL){
return 1;
}
EVP_MD_CTX *evpCtx = EVP_MD_CTX_new();
const EVP_MD *md = EVP_get_digestbyname(algorithms);
if(md==NULL){
return 2;
}
EVP_DigestInit_ex(evpCtx,md, NULL);
unsigned char inbuf[1024] = {0};
int inlen = 0;
while((inlen = fread(inbuf,1,sizeof(inbuf),fp1))){
EVP_DigestUpdate(evpCtx,inbuf,inlen);
}
unsigned char result[MAX_DIGEST_LENGTH] = {0};
int result_len=0;
EVP_DigestFinal_ex(evpCtx, result, &result_len);
fwrite(result,1,result_len,fp2);
fflush(fp2);
fclose(fp1);
fclose(fp2);
EVP_MD_CTX_free(evpCtx);
return 0;
}
int main(int argc,const char* argv[]){
int r = SM3_digest(argv[1],argv[2],argv[3]);
if(r==1){
printf("unknown file %s\n",argv[2]);
printf("usage: ./a.out sm3 infile outfile");
}else if(r==2){
printf("unknown algorithms %s\n",argv[1]);
printf("usage: ./a.out sm3 infile outfile");
printf("support : SM3 | SHA256 | SHA512 | SHA224 | SHA384 | MD5\n");
}
return 0;
}
运行结果:SM3
运行结果:SHA256
运行结果:SHA512
运行结果:SHA384
运行结果:MD5