黑客24小时在线接单的网站

黑客24小时在线接单的网站

手把手教你如何实现一个简单的数据加解密算法

本文,一口君带大家实现了一种简单而实用的加密方法,

让您了解实际项目开发中数据加密的过程。

一、网络通信常用的加密过程

关于加密的算法很多,实际实现过程千差万别,

下图是网络通信加密的常见应用场景。

密码机的一些说明:

                   
  • 客户端服务器端可以设置密码机(可以是软件,也可以是硬件,只要能在本地或服务器上生成密钥)
  •                
  • keygen同步码会影响密码机生成的密钥序列
  •                
  • 密码机在keygen在与同步码相同的情况下,会产生相同的密钥序列。加解密方需要记住产生密钥的顺序,并申请解密数据的密钥
  •                

如上图所示,基于C/S架构服务器和客户端通信模型,

如果客户端想向服务器发送加密密文,C/S需要交互的过程。

1    服务器端发送密钥密文

首先,服务器端和客户端务器端和客户端

服务器端随机生成密钥keygen,并使用默认密钥对keygen加密,生成密钥密文

客户端可以通过命令定期请求该密钥密文或者服务器定时下发

客户端收到密钥密文后,也可以通过默认密钥解密获得明文keygen

2. 客户端加密数据

在发送数据之前,客户端首先生成同步码

将同步码和keygen设置密码机,然后向密码机申请一定长度的密钥

通过一定的算法加密明文和密钥(通常是异或),生成数据密文

3. 客户端发送同步码和数据密文

客户端向服务器发送数据密文和同步码明文

服务器提取同步码

4. 服务器端接收数据并解密

服务器将keygen与密码机设置同步码,同时申请一定数量的密钥

服务器根据密钥解密,即获得相应的明文

此时服务器和客户端使用相同的服务器keygen,与同步码相同,因此双方申请的密钥序列必须相同。

二、函数实现

以下是加密算法的一些函数原型和功能描述,基本实现了第一节的功能。

1. 申请加密密钥函数request_key

  • intrequest_key(intsync,intkey_num,charkey[])
  • 功能:
  • 如果不设置新的密码,向密码机申请一定数量的加密数据密钥keygen,然后生成的密码将按顺序生成。每次申请密钥时,都会记录上次生成的密钥偏移。下次申请时,密钥将继续从上一个位置分配
  • 参数:
  • sync:密码机根据此同步生成随机序列的密钥
  • key_num:申请的密钥个数
  • key:申请的密钥存储缓存
  • 返回值:
  • 实际返回密钥数量
  • 2. 设置密钥序列函数set_keygen

  • voidset_keygen(intkey)
  • 功能:
  • 设置密码机keygen,设置后会影响随机密钥序列
  • 参数:
  • key:密钥
  • 返回值:
  • 3. 产生随机数born_seed

  • intborn_seed(intsync,intkey)
  • 功能:
  • 根据同步码和keygen生成随机密钥种子
  • 参数:
  • sync:同步码
  • key:密钥
  • 返回值:
  • 种子
  • 4. 重置keygen reset_keygen()

  • voidreset_keygen()
  • 功能:
  • 重置keygen,随机数序列会影响生成
  • 三、测试代码实例

    最终文件如下:

  • key.ckey.hmain.c
  • 示例1 检测产生的随机序列

  • intmain(intargc,char*argv[])
  • {
  • inti;
  • unsignedintlen;
  • intj,r,key_num;
  • unsignedintsync=0;
  • unsignedcharkey[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]
  • a552c8145df7465b8942
  • 密钥10-19:----[10]
  • 38696fa608d26939cd29
  • --------------采用keygen=1234同步码=0产生密文----------------
  • 密钥0-9:----[10]
  • 0e830b73ecf54b4a7435
  • 密钥10-19:----[10]
  • e7f10641c86baadf0c3d
  • 可以看到不同的用途keygen随机序列不同。

    如果设置不同的同步码,序列仍然会不同。

    例2 默认使用keygen,加解密

  • chardata0[10]={
  • 0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0x10,
  • };
  • intmain(intargc,char*argv[])
  • {
  • inti;
  • unsignedintlen;
  • intj,r,key_num;
  • unsignedintsync=0;
  • unsignedcharkey[MAX_KEY_REQUEST];
  • charbuf[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<len;i )
  • {
  • buf[i]=data0[i]^key[i];
  • }
  • print_array("\n密文:",buf,len);
  • printf("\n--------------------开始解密--------------------\n");
  • reset_keygen();
  • memset(key,0,sizeof(key));
  • len=request_key(sync,key_num,key);
  • for(i=0;i<len;i )
  • {
  • buf[i]=buf[i]^key[i];
  • }
  • print_array("\n明文:",buf,len);
  • }
  • 测试结果

  • --------------采用默认keygen开始加密----------------
  • 明文:----[10]
  • 01020304050607080910
  • 密钥:----[10]
  • a552c8145df7465b8942
  • 密文:----[10]
  • a450cb1058f141538052
  • --------------------开始解密--------------------
  • 明文:----[10]
  • 01020304050607080910
  • 示例3 用不同的keygen加解密同步码

  • intmain(intargc,char*argv[])
  • {
  • inti;
  • unsignedintlen;
  • intj,r,key_num;
  • unsignedintsync=0;
  • unsignedcharkey[MAX_KEY_REQUEST];
  • charbuf[120]={0};
  • unsignedintmykeygen;
  • if(argc!=4){
  • fprintf(stderr,"Usage:%s<seed><keynum><keygen>\n",argv[0]);
  • exit(EXIT_FAILURE);
  • }
  • sync=atoi(argv[1]);
  • key_num=atoi(argv[2]);
  • mykeygen=atoi(argv[3]);
  • printf("\n--------------自定义keygen、同步码开始加密----------------\n");
  • set_keygen(mykeygen);
  • 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<len;i )
  • {
  • buf[i]=data0[i]^key[i];
  • }
  • print_array("\n密文:",buf,len);
  • printf("\n--------------------开始解密--------------------\n");
  • set_keygen(mykeygen);
  • memset(key,0,sizeof(key));
  • len=request_key(sync,key_num,key);
  • for(i=0;i<len;i )
  • {
  • buf[i]=buf[i]^key[i];
  • }
  • print_array("\n明文:",buf,len);
  • exit(EXIT_SUCCESS);
  • }
  • 执行结果如下:

  • --------------自定义keygen、同步码开始加密----------------
  • 明文:----[10]
  • 01020304050607080910
  • 密钥:----[10]
  • 530029cd27ebcc801ad7
  • 密文:----[10]
  • 52022ac922edcb8813c7
  • --------------------开始解密--------------------
  • 明文:----[10]
  • 01020304050607080910
  • 可见我们的确实现了数据的加密和解密。

    四、实际使用数据加密

    假设我们使用上述实例代码将相应的功能移植到C/S两端,

    完整的数据加密和数据传输参考流程如下:

    记住,只要双方设置相同的设置keygen密码机吐出的密钥与同步码相同,

    每次客户发送报纸,都会将自己的明文同步码发送给服务器,

    根据提前发送给客户端的服务器keygen解密操作可以通过同步码实现,

    虽然可以看到明文的同步码,

    但是,还需要解决服务器发布的密码算法和算法keygen密文。

    五、 原理

    实现加密算法的主要问题是如何产生随机序列作为密钥。

    本例是借用库函数rand() 原型如下:

  • #include
  • intrand(void);
  • 函数rand() 虽然可以产生随机序列,但每次产生的序列实际上是一样的。

  • #include<stdio.h>
  • main()
  • {
  • inti=0;
  • for(i=0;i<10;i )
  • {
  • printf("%d",rand());
  • }
  • putchar('\n');
  • }
  • 运行结果如下:

  • peng@peng-virtual-machine:/mnt/hgfs/peng/rand/code$./a.out
  • 180428938384693088616816927771714636915195774779342423833571988538616497604925965166491189641421
  • peng@peng-virtual-machine:/mnt/hgfs/peng/rand/code$./a.out
  • 180428938384693088616816927771714636915195774779342423833571988538616497604925965166491189641421
  • 每次都要产生不同的随机序列怎么办?需要借助srand()函数

  • voidsrand(unsignedintseed);
  • 种子只需要通过这个函数设置,生成的序列就会完全不同,

    通常我们用time()返回值作为种子,

    在这里,我们随便写几个数据来测试函数

  • #include<stdio.h>
  • main()
  • {
  • inti=0;
  • srand(111);
  • for(i=0;i<10;i )
  • {
  • printf("%d",rand());
  • }
  • putchar('\n');
  • srand(1111);
  • for(i=0;i<10;i )
  • {
  • printf("%d",rand());
  • }
  • putchar('\n');
  • }
  • 执行结果如下:

  • peng@peng-virtual-machine:/mnt/hgfs/peng/rand/code$./a.out
  • 16299058617080174771225010071144441133248376142112273117116638451315391342731883039818779189906
  • 13837119248824326741555165704133486349514746795546767966451547219795348682851892754119100411878
  • 输入不同的种子会产生不同的序列。

    函数原型如下:

    图片本例原理比较简单,不考虑太复杂的应用(如多路密钥管理)和数据安全性,

    这种加密算法属于对称加密,相对简单,或者相对容易破解,仅用于学习和理解加密过程。

    目前,专业公司和团队在市场上实现加解密功能。

    本文转载自微信公众号「一口Linux」,请注意以下二维码。请联系本文Linux公众号。

       
    • 评论列表:
    •  痴者怎忘
       发布于 2022-06-04 16:11:48  回复该评论
    • 本文,一口君带大家实现了一种简单而实用的加密方法,让您了解实际项目开发中数据加密的过程。一、网络通信常用的加密过程关于加密的算法很多,实际实现过程千差万别,下图是网络通信加密的常见应用场景。密码机的一些说明:  
    •  依疚杞胭
       发布于 2022-06-04 16:26:50  回复该评论
    • df0c3d可以看到不同的用途keygen随机序列不同。如果设置不同的同步码,序列仍然会不同。例2 默认使用keygen,加解密chardata0[10]={0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0x10,};intma

    发表评论:

    Powered By

    Copyright Your WebSite.Some Rights Reserved.