
本文,一口君带着大家自己实现一个简单但也很实用的加密方法,
让大家了解实际项目开发中数据加密的流程。
一、一种常见的网络通信的加密流程
关于加密的算法很多,实际实现过程千差万别,
下图是一个常见的网络通信加密的应用场景。
密码机的一些说明:
- 客户端服务器端都可以设置密码机(可以是软件、也可以是一个硬件,可以在本地也可以在某个服务器上,只要能够产生密钥即可)
- keygen和同步码都会影响到密码机生成的密钥序列
- 密码机在keygen和同步码相同的情况下,会产生相同的密钥序列,加解密双方需要记住产生密钥的顺序,解密多少数据就申请多少密钥

如上图所示,基于C/S架构的服务器和客户端通信模型,
下面以客户端如果要发送一段加密的密文给服务器,C/S需要交互的流程。
1 服务器端发送密钥密文
首先服务器端、客户端都保存了一个默认的密钥
服务器端随机生成密钥keygen,并使用该默认密钥对keygen加密,生成密钥密文
客户端可以通过命令定期请求该密钥密文或者服务器定时下发
客户端收到密钥密文后,也可以通过默认密钥进行解密得到明文的keygen
2. 客户端对数据加密
客户端在发送数据之前,首先生成一个同步码
将同步码和keygen设置给密码机,然后向密码机申请一定长度的密钥
将明文和密钥通过一定的算法进行加密(通常是异或),生成数据密文
3. 客户端发送同步码和数据密文
客户端将数据密文和同步码明文一起发送给服务器
服务器提取出同步码
4. 服务器端接收数据并解密
服务器将keygen和同步码设置给密码机,同时申请一定数量的密钥
服务器根据密钥对密文进行解密,即得到对应的明文
因为服务器和客户端此时都使用了相同的keygen,和同步码,所以双方申请的密钥序列一定是一样的。
二、函数实现
下面是一口君实现的加密算法的一些函数原型以及功能说明,这些函数基本实现了第一节的功能。
1. 申请加密密钥函数request_key
- int request_key(int sync,int key_num,char key[])
- 功能:
- 向密码机申请一定数量的用于加密数据的密钥,如果不设置新的keygen,那么生成的密码会顺序产生下去,每次申请密钥都会记录上次生成的密钥的偏移,下次在申请的时候,都会从上一位置继续分配密钥
- 参数:
- sync:同步码,密码机依据此同步产生随机序列的密钥
- key_num:申请的密钥个数
- key:申请的密钥存储的缓存
- 返回值:
- 实际返回密钥个数
2. 设置密钥序列函数set_keygen
- void set_keygen(int key)
- 功能:
- 向密码机设置keygen,设置后会影响产生的随机密钥序列
- 参数:
- key:密钥
- 返回值:
- 无
3. 产生随机数born_seed
- int born_seed(int sync,int key)
- 功能:
- 根据同步码和keygen生成随机密钥种子
- 参数:
- sync:同步码
- key:密钥
- 返回值:
- 种子
4. 重置keygen reset_keygen()
- void reset_keygen()
- 功能:
- 重置keygen,会影响生成的随机数序列
三、测试代码实例
最终文件如下:
- key.c key.h main.c
示例1 检测产生的随机序列
- int main(int argc, char *argv[])
- {
- int i;
- unsigned int len;
- int j, r, key_num;
- unsigned int sync = 0;
- unsigned char key[MAX_KEY_REQUEST];
- key_num = 10;
- printf("\n--------------采用默认keygen 同步码=0 产生密文----------------\n");
- reset_keygen();
- memset(key,0,sizeof(key));
- len = request_key(sync,key_num,key);
- print_array("密钥0-9:",key,len);
- memset(key,0,sizeof(key));
- len = request_key(sync,key_num,key);
- print_array("密钥10-19:",key,len);
- printf("\n--------------采用keygen=1234 同步码=0 产生密文----------------\n");
- set_keygen(1234);
- memset(key,0,sizeof(key));
- len = request_key(sync,key_num,key);
- print_array("密钥0-9:",key,len);
- memset(key,0,sizeof(key));
- len = request_key(sync,key_num,key);
- print_array("密钥10-19:",key,len);
- }
执行结果:
- --------------采用默认keygen 同步码=0 产生密文----------------
- 密钥0-9: ----[10]
- a5 52 c8 14 5d f7 46 5b 89 42
- 密钥10-19: ----[10]
- 38 69 6f a6 08 d2 69 39 cd 29
- --------------采用keygen=1234 同步码=0 产生密文----------------
- 密钥0-9: ----[10]
- 0e 83 0b 73 ec f5 4b 4a 74 35
- 密钥10-19: ----[10]
- e7 f1 06 41 c8 6b aa df 0c 3d
可以看到采用不同的keygen产生的随机序列是不一样的。
如果设置不同的同步码,仍然序列还会不一样。
示例2 用默认keygen,加解密
- char data0[10]={
- 0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0x10,
- };
- int main(int argc, char *argv[])
- {
- int i;
- unsigned int len;
- int j, r, key_num;
- unsigned int sync = 0;
- unsigned char key[MAX_KEY_REQUEST];
- char buf[120]={0};
- key_num = 10;
- printf("\n--------------采用默认keygen开始加密----------------\n");
- reset_keygen();
- print_array("\n明文:",data0,key_num);
- memset(key,0,sizeof(key));
- len = request_key(sync,key_num,key);
- print_array("密钥:",key,len);
- for(i=0;i








发表评论
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。