密码工程学习笔记1
知识点归纳
最有收获的内容
攻击者具有很大的优势
-
攻击者只需要有效利用一个漏洞,便能攻破系统。这个漏洞不一定来自系统最薄弱的环节。
-
防御者不仅需要不断加强最薄弱的环节(木桶原理),还要兼顾整个系统的所有环节。即使已经堵住了成千上万的漏洞,但只要还剩一个,就完了。
-
人类自身,往往是脆弱的环节。诈骗、威胁、收买、反目成仇......
降低系统复杂度
-
一个系统越复杂,就越有可能出现安全问题。
-
使一个系统简单的最有效方法就是把它模块化。将系统拆解为一个个模块,在系统的不同模块之间提供清晰而简单的接口。
-
一个好的模块及其接口,应能做到将系统的其他组件与自身的技术细节隔离开来。
遇到的问题与解决过程
SM4的key和iv怎么生成?
最开始看的别人的博客,用的BN里的函数
int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
BN_rand()生成长度为bits位的伪随机位数,并将其存储在rnd中。
top参数指定对生成的数据的最高有效位的要求,数字如果是BN_RAND_TOP_ANY,则没有约束。如果是BN_RAND_TOP_ONE,则顶部位必须为1。如果bottom是BN_RAND_bottom_ODD,则数字将为奇数;
后来才发现EVP中有随机生成密钥的函数,所以还是要仔细阅读官方文档和man手册。
EVP_CIPHER_CTX_rand_key(ctx,sm4key->key);
SM4加密大文件不成功。
大文件,由于大于缓冲区的大小,所以需要循环读取并循环加密里面的内容。所以要在循环里面update,把Final函数放到循环外面。
最开始对update和final的理解不深刻,把final也放在循环里面了,所以有问题。
再就是要及时fflush
最后就是outbuf要比inbuf大一些(在实验中,只要大几个字节就基本没问题)如果相等可能在加密大文件时会发生意外。
实践内容
使用OpenSSL EVP实现SM4加密文件
typedef struct
{
unsigned char key[16];
unsigned char iv[16];
}sm4_key_t;
int SM4_genKey(const EVP_CIPHER *type,sm4_key_t *sm4key){
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(ctx);
EVP_EncryptInit_ex(ctx,type,NULL,NULL,NULL);
EVP_CIPHER_CTX_rand_key(ctx,sm4key->key);
EVP_CIPHER_CTX_rand_key(ctx,sm4key->iv);
return 1;
}
//输入对称加密算法 和 加密模式
//输出密文到文件
int SM4_encrypt(const EVP_CIPHER *type,sm4_key_t *sm4key,const char *filename,const char *outfilename){
//初始化
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(ctx);
EVP_EncryptInit_ex(ctx,type,NULL,sm4key->key,sm4key->iv);
//打开输入文件
unsigned char inbuf[1024] = {0};
unsigned char outbuf[4096] = {0};
int outlen;
FILE *fp1 = fopen(filename,"rb");
FILE *fp2 = fopen(outfilename,"wb");
//读取文件内容,加密,结果输出到缓冲区
int inlen = 0;
while((inlen = fread(inbuf,1,sizeof(inbuf),fp1))){
EVP_EncryptUpdate(ctx,outbuf,&outlen,inbuf,inlen);
fwrite(outbuf,1,outlen,fp2);
fflush(fp2);
}
int finlen;
EVP_EncryptFinal_ex(ctx,outbuf,&finlen);
fwrite(outbuf,1,finlen,fp2);
fflush(fp2);
fclose(fp1);
fclose(fp2);
EVP_CIPHER_CTX_cleanup(ctx);
return 1;
}
最后diff命令输出为空,说明自己代码实现的SM4加密,与openssl命令的输出结果一致
微精通
《Windows C/C++ 加解密实战》
Linux man -k命令 grep -nr命令