密码工程学习笔记1

知识点归纳

最有收获的内容

攻击者具有很大的优势

  1. 攻击者只需要有效利用一个漏洞,便能攻破系统。这个漏洞不一定来自系统最薄弱的环节。

  2. 防御者不仅需要不断加强最薄弱的环节(木桶原理),还要兼顾整个系统的所有环节。即使已经堵住了成千上万的漏洞,但只要还剩一个,就完了。

  3. 人类自身,往往是脆弱的环节。诈骗、威胁、收买、反目成仇......

降低系统复杂度

  • 一个系统越复杂,就越有可能出现安全问题。

  • 使一个系统简单的最有效方法就是把它模块化。将系统拆解为一个个模块,在系统的不同模块之间提供清晰而简单的接口。

  • 一个好的模块及其接口,应能做到将系统的其他组件与自身的技术细节隔离开来。

遇到的问题与解决过程

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++ 加解密实战》

博客:EVP中文手册

OpenSSL官方文档

Linux man -k命令 grep -nr命令

posted @ 2023-02-28 15:16  191206  阅读(68)  评论(0编辑  收藏  举报