一种DES和RSA混合加密的通信系统

这篇具有很好参考价值的文章主要介绍了一种DES和RSA混合加密的通信系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

0 引言

1 RSA和DES原理概述

1.1 DES算法

1.2 RSA算法

2 系统架构

3 实验及结果分析

3.1 RSA加密传送密钥

3.2 DES加密通信内容

4 总结

参考文献

参考代码:


缺陷:引言总结前人观点不够精炼,还需要简述本文和前人工作的关系。另外,需要描述解决对称密钥分发的过程,使得内容更加完整。

0 引言

        随着通信技术的不断发展和人们需求的增加,使得通信安全问题越来越受到广泛的关注,而创造敏感信息的安全传输环境一直是学术界重要的研究内容。例如,行鸿彦[[i]]等人设计了一种特殊的保密通信系统,在使用脉冲同步技术的基础上,结合压缩检测技术,增强了通信系统的安全性;骆钊[ii]等人提供了一套基于IEC62351通信协议的身份认证机制,并提供了通过SM双密码系统安全传输目标通信消息的方案,有效解决了变电站通信报文的数据安全性和实时性要求;冷飞[iii]等人指出这种RSA融合高阶数据加密算法(AES)的新加密算法,采用了AES计算并配合了RSA加密方式,可以充分地发挥AES计算运行速率快、RSA加密方式配置性能高等的优点;Kaya和Selçuk[iv]将中国剩余定理的方法引进了门限设定密码理论中,并使用该方法建立了门限设定的RSA签名方法,极大地提高了保密性。上述加密通信方法在各自的应用领域产生了一些积极影响。本文结合DES算法和RSA算法,利用socket网络编程技术设计了一个基于C++的通信系统。

1 RSA和DES原理概述

1.1 DES算法

    DES属于分组密码,也称为对称密码体制。它要求先对信息进行分类,然后加密和解密的组装。由内容的发出和收到方存储用以加密和解密信息的密钥。加密和解密密钥在获取其中之一时就可以利用相关数学公式互相推出。

    置换IP后,将明文分为两组三十二位,接着再进行十六轮迭代的乘积变换,每次变换的结果仍然为三十二位。每次得出的结果,再与下一位密钥进行计算。通过了十六轮运算以后,再把两截内容连接起来,并进行逆置换,就可以获得最终的密文。明文和密文有效的长度均为六十四位,而密钥长度虽然也是六十四位,但有效的部分仅有五十六位。

1.2 RSA算法

        RSA作为一种公开密钥密码体制,具有十分出色的安全性,认可度较高。因为公钥和私钥的产生是基于数学原理“可以轻易寻求两个大素数,但极难将它们的成绩分解开”,因此安全性较高。首先准备两个较大质数,分别命名为p,q,使得N=pq,N难以因式分解成原来的p和q。于是根据RSA算法的原理,令k=(q-1)(p-1)选择一个整数e,使得e与k互质且e小于k,并且令d*e1(mod k),此时,e是公钥,d是私钥。对于一份资料数据,如果使用私钥对其加密,那么我们只有使用与之匹配的公钥才能解开;而当我们使用公钥加密,那为了解开加密文本我们就需要使用私钥。

2 系统架构

通信系统的通信框架,采用了Socket服务器和客户端的通信模型,在此基础上选择了TCP协议,如图 1所示。此外,它还结合了C++的多线程来实现通信。首先,Server建立服务器监听socket套接字,等待并接受Client创建连接socket套接字后发送到Server的请求,然后Server在接受请求后创建socket。此时,Server可以与Client进行通信。最后,Server和Client关闭套接字和相关资源,通信在此结束。

一种DES和RSA混合加密的通信系统

 

                                                         图 1:通信系统的通信框架

        通讯体系所采纳的加密方式是DES和RSA的组合加密,如图 2所示。DES算法的长处是加密处理简单,且速度较快,但不足是不能保证密钥的安全转移;RSA算法的亮点在于它极高的安全性,但美中不足的是缓慢的加密速度。本文的通信系统采用公开密钥体制RSA加密传输对称密码算法密钥,对称密码体制DES加密通信的内容。服务器Server首先使用RSA算法生成公钥和私钥,公开公钥,使用私钥对DES算法密钥进行加密,然后再把加密之后的文本发送回客户端Client。客户端Client使用公钥解密密文以获取对称密码算法密钥,然后就可以利用对称密码体制对内容进行加密通信。

一种DES和RSA混合加密的通信系统

         ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        2 :混合加密通信

3 实验及结果分析

        本文设计了一个基于C ++ 平台的安全通信系统。采用了TCP网络协议和Socket套接字,来实现通信系统的通信部分。RSA算法用于加密对称密码并将其发送到通信对象。对称密码体制采取DES加密标准,用以加密通信内容。以下实验数据都是在操作系统Ubuntu 20.04上实现的。

3.1 RSA加密传送密钥

        首先在Qt上运行程序,按照提示选择服务端,输入s,然后再输入DES算法的对称密码,可以看到加密密文和加密成功等待发送的提示,如图 3所示;此时再次运行程序,根据提示选择客户端,输入c,就可以在客户端上看到解密后的密文,如图 4所示。

一种DES和RSA混合加密的通信系统

                                        图 3:Server界面截图

一种DES和RSA混合加密的通信系统

                                 4:Client界面截图

3.2 DES加密通信内容

        分别在服务端和客户端上输入上文选定的DES对称密码密钥,即可开始通信,如图 5和图 6所示。最后根据提示,输入“quit”结束通信。

一种DES和RSA混合加密的通信系统

                                 5:Server界面截图

一种DES和RSA混合加密的通信系统

         ​​​​​​​        ​​​​​​​        ​​​​​​​        6:Client界面截图

4 总结

    服务器Server可以正常加密DES算法的密码密钥,并将加密之后内容发送给客户端Client;客户端Client也可以正常连接到服务器Server,并向服务器Server发送请求。在通信系统中,当RSA算法满足一定条件时,可以认为它是无法破解的。同时,采取DES密码体制对通信内容实施加密,有效提升了通信过程中的数据加解密效率。实验结果显示,所设计的DES和RSA加密混合通信系统可有满足一定程度上的安全通信,对通信系统的安全设计具备一定的参考意义。

参考文献


[i] 行鸿彦,冒海微,徐伟,王秋辉.基于压缩感知的脉冲同步的混沌保密通信系统[J].仪器仪表学报,2014,35(07):1510-1517.DOI:10.19650/j.cnki.cjsi.2014.07.009.

[ii]  骆钊,谢吉华,顾伟,严童,王志贺,林英俊.SM2加密体系在智能变电站站内通信中的应用[J].电力系统自动化,2015,39(13):116-123.

[iii] 冷飞, 徐进华, 栾仕喜. RSA 融合 AES 算法的网络信息安全方法[J]. 华侨大学学报: 自然科学版, 2017, 38(1): 117-120.

[iv]  Kaya K and Selçuk A A. Threshold cryptography based on Asmuth-Bloom secret sharing[J]. Information Sciences, 2007, 177(19): 4148-4160.

参考代码:

CDes.cpp:

#include"CDes.h"

//初始置换表
const static unsigned char pc_first[64] = {
	58 , 50 , 42 , 34 , 26 , 18 , 10 , 2 , 60 , 52 , 44 , 36 , 28 , 20 , 12 , 4 ,
	62 , 54 , 46 , 38 , 30 , 22 , 14 , 6 , 64 , 56 , 48 , 40 , 32 , 24 , 16 , 8 ,
	57 , 49 , 41 , 33 , 25 , 17 , 9 , 1 , 59 , 51 , 43 , 35 , 27 , 19 , 11 , 3 ,
	61 , 53 , 45 , 37 , 29 , 21 , 13 , 5 , 63 , 55 , 47 , 39 , 31 , 23 , 15 , 7
} ;

//扩展置换,将数据从32位扩展为48位
static const unsigned char des_E[48] = {
	32 , 1 , 2 , 3 , 4 , 5 , 4 , 5 , 6 , 7 , 8 , 9 , 8 , 9 , 10 , 11 ,
	12 , 13 , 12 , 13 , 14 , 15 , 16 , 17 , 16 , 17 , 18 , 19 , 20 , 21 , 20 , 21 ,
	22 , 23 , 24 , 25 , 24 , 25 , 26 , 27 , 28 , 29 , 28 , 29 , 30 , 31 , 32 , 1
} ;

//S盒子代替
const static unsigned char des_S[8][64]={
       	{//S1盒子
	14 , 4 , 13 , 1 , 2 , 15 , 11 , 8 , 3 , 10 , 6 , 12 , 5 , 9 , 0 , 7 ,
       	0 , 15 , 7 , 4 , 14 , 2 , 13 , 1 , 10 , 6 , 12 , 11 , 9 , 5 , 3 , 8 ,
       	4 , 1 , 14 , 8 , 13 , 6 , 2 , 11 , 15 , 12 , 9 , 7 , 3 , 10 , 5 , 0 ,
       	15 , 12 , 8 , 2 , 4 , 9 , 1 , 7 , 5 , 11 , 3 , 14 , 10 , 0 , 6 , 13
} ,
	{//S2盒子
       	15 , 1 , 8 , 14 , 6 , 11 , 3 , 4 , 9 , 7 , 2 , 13 , 12 , 0 , 5 , 10 ,
       	3 , 13 , 4 , 7 , 15 , 2 , 8 , 14 , 12 , 0 , 1 , 10 , 6 , 9 , 11 , 5 ,
       	0 , 14 , 7 , 11 , 10 , 4 , 13 , 1 , 5 , 8 , 12 , 6 , 9 , 3 , 2 , 15 ,
       	13 , 8 , 10 , 1 , 3 , 15 , 4 , 2 , 11 , 6 , 7 , 12 , 0 , 5 , 14 , 9
} ,
	{//S3盒子
       	10 , 0 , 9 , 14 , 6 , 3 , 15 , 5 , 1 , 13 , 12 , 7 , 11 , 4 , 2 , 8 ,
       	13 , 7 , 0 , 9 , 3 , 4 , 6 , 10 , 2 , 8 , 5 , 14 , 12 , 11 , 15 , 1 ,
       	13 , 6 , 4 , 9 , 8 , 15 , 3 , 0 , 11 , 1 , 2 , 12 , 5 , 10 , 14 , 7 ,
       	1 , 10 , 13 , 0 , 6 , 9 , 8 , 7 , 4 , 15 , 14 , 3 , 11 , 5 , 2 , 12
} ,
	{//S4盒子
       	7 , 13 , 14 , 3 , 0 , 6 , 9 , 10 , 1 , 2 , 8 , 5 , 11 , 12 , 4 , 15 ,
       	13 , 8 , 11 , 5 , 6 , 15 , 0 , 3 , 4 , 7 , 2 , 12 , 1 , 10 , 14 , 9 ,
       	10 , 6 , 9 , 0 , 12 , 11 , 7 , 13 , 15 , 1 , 3 , 14 , 5 , 2 , 8 , 4 ,
       	3 , 15 , 0 , 6 , 10 , 1 , 13 , 8 , 9 , 4 , 5 , 11 , 12 , 7 , 2 , 14
} ,
       	{//S5盒子
	2 , 12 , 4 , 1 , 7 , 10 , 11 , 6 , 8 , 5 , 3 , 15 , 13 , 0 , 14 , 9 ,
       	14 , 11 , 2 , 12 , 4 , 7 , 13 , 1 , 5 , 0 , 15 , 10 , 3 , 9 , 8 , 6 ,
       	4 , 2 , 1 , 11 , 10 , 13 , 7 , 8 , 15 , 9 , 12 , 5 , 6 , 3 , 0 , 14 ,
       	11 , 8 , 12 , 7 , 1 , 14 , 2 , 13 , 6 , 15 , 0 , 9 , 10 , 4 , 5 , 3
} ,
       	{//S6盒子
	12 , 1 , 10 , 15 , 9 , 2 , 6 , 8 , 0 , 13 , 3 , 4 , 14 , 7 , 5 , 11 ,
       	10 , 15 , 4 , 2 , 7 , 12 , 9 , 5 , 6 , 1 , 13 , 14 , 0 , 11 , 3 , 8 ,
       	9 , 14 , 15 , 5 , 2 , 8 , 12 , 3 , 7 , 0 , 4 , 10 , 1 , 13 , 11 , 6 ,
       	4 , 3 , 2 , 12 , 9 , 5 , 15 , 10 , 11 , 14 , 1 , 7 , 6 , 0 , 8 , 13
} ,
	{//S7盒子
       	4 , 11 , 2 , 14 , 15 , 0 , 8 , 13 , 3 , 12 , 9 , 7 , 5 , 10 , 6 , 1 ,
       	13 , 0 , 11 , 7 , 4 , 9 , 1 , 10 , 14 , 3 , 5 , 12 , 2 , 15 , 8 , 6 ,
       	1 , 4 , 11 , 13 , 12 , 3 , 7 , 14 , 10 , 15 , 6 , 8 , 0 , 5 , 9 , 2 ,
       	6 , 11 , 13 , 8 , 1 , 4 , 10 , 7 , 9 , 5 , 0 , 15 , 14 , 2 , 3 , 12
} ,
	{//S8盒子
       	13 , 2 , 8 , 4 , 6 , 15 , 11 , 1 , 10 , 9 , 3 , 14 , 5 , 0 , 12 , 7 ,
       	1 , 15 , 13 , 8 , 10 , 3 , 7 , 4 , 12 , 5 , 6 , 11 , 0 , 14 , 9 , 2 ,
       	7 , 11 , 4 , 1 , 9 , 12 , 14 , 2 , 0 , 6 , 10 , 13 , 15 , 3 , 5 , 8 ,
       	2 , 1 , 14 , 7 , 4 , 10 , 8 , 13 , 15 , 12 , 9 , 0 , 3 , 5 , 6 , 11
}
} ;

//P盒置换
const static unsigned char des_P[32] = {
	16 , 7 , 20 , 21 , 29 , 12 , 28 , 17 , 1 , 15 , 23 , 26 , 5 , 18 , 31 , 10 ,
	2 , 8 , 24 , 14 , 32 , 27 , 3 , 9 , 19 , 13 , 30 , 6 , 22 , 11 , 4 , 25
} ;

//末置换
const static unsigned char pc_last[64] = {
	40 , 8 , 48 , 16 , 56 , 24 , 64 , 32 , 39 , 7 , 47 , 15 , 55 , 23 , 63 , 31 ,
	38 , 6 , 46 , 14 , 54 , 22 , 62 , 30 , 37 , 5 , 45 , 13 , 53 , 21 , 61 , 29 ,
	36 , 4 , 44 , 12 , 52 , 20 , 60 , 28 , 35 , 3 , 43 , 11 , 51 , 19 , 59 , 27 ,
	34 , 2 , 42 , 10 , 50 , 18 , 58 , 26 , 33 , 1 , 41 , 9 , 49 , 17 , 57 , 25
} ;

//密钥置换表,将64位密钥置换压缩置换为56位
const static unsigned char pctable[56] = {
	57 , 49 , 41 , 33 , 25 , 17 , 9 , 1 ,
	58 , 50 , 42 , 34 , 26 , 18 , 10 , 2 ,
	59 , 51 , 43 , 35 , 27 , 19 , 11 , 3 ,
	60 , 52 , 44 , 36 , 63 , 55 , 47 , 39 ,
	31 , 23 , 15 , 7 , 62 , 54 , 46 , 38 ,
	30 , 22 , 14 , 6 , 61 , 53 , 45 , 37 ,
	29 , 21 , 13 , 5 , 28 , 20 , 12 , 4
} ;

//每轮移动的位数
const static unsigned char lefttable[16] = {
	1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1
} ;

//压缩置换表,56位密钥压缩位48位密钥
const static unsigned char keychoose[48] = {
	14 , 17 , 11 , 24 , 1 , 5 , 3 , 28 ,
	15 , 6 , 21 , 10 , 23 , 19 , 12 , 4 ,
	26 , 8 , 16 , 7 , 27 , 20 , 13 , 2 ,
	41 , 52 , 31 , 37 , 47 , 55 , 30 , 40 ,
	51 , 45 , 33 , 48 , 44 , 49 , 39 , 56 ,
	34 , 53 , 46 , 42 , 50 , 36 , 29 , 32
} ;

int CDes::ip(const Block & block , HBlock & left , HBlock & right)
{
    for(size_t i = 0 ; i < right.size() ; i++)
		right[i] = block[pc_first[i] - 1] ;//获取初始置换的右半部分
	for(size_t i = 0 ; i < left.size() ; i++)
		left[i] = block[pc_first[i + right.size()] - 1] ;//获取初始置换的左半部分
	return 0 ;
}

int CDes::genkey(const Block & bkey) 
{
    //n在区间[0,15]之间取值,bkey为64位密钥
	Code result ;//返回值,48位子密钥
	Key key ;//56位密钥
	unsigned int klen = key.size() , rlen = result.size() ;//分别为56和48
	//获取56位密钥
	for(size_t i = 0 ; i < key.size() ; i++)
		key[i] = bkey[pctable[i] - 1] ;//密钥置换
	for(size_t i = 0 ; i < SUBKEYNUM ; i++)
	{//循环移位
		for(size_t j = 0 ; j < lefttable[i] ; j++)
		{
			//将密钥循环位暂存在result中
			result[rlen - lefttable[i] + j] = key[klen - lefttable[i] + j] ;
			result[rlen / 2 - lefttable[i] + j] = key[klen / 2 - lefttable[i] + j] ;
		}	
		key <<= lefttable[i] ;//移位
		for(size_t j = 0 ; j < lefttable[i] ; j++)
		{
			//写回key中
			key[klen / 2 + j] = result[rlen - lefttable[i] + j] ;
			key[j] = result[rlen / 2 - lefttable[i] + j] ;
		}
        //压缩置换
        for(size_t i = 0 ; i < result.size() ; i++)
            result[i] = key[keychoose[i] - 1] ;
        subkey[i] = result;
	}

	return 0;
}

int CDes::des_once(HBlock & left , HBlock & right , const Code & subkey)
{
    Code code ;//48位数据块
	HBlock pcode ;//32位数据块
	//将右半部分扩展为48位
	for(size_t i = 0 ; i < code.size() ; i++)
		code[i] = right[des_E[i] - 1] ;//选择扩展运算
	code ^= subkey ;//密钥加运算,与子密钥异或
	//S盒代替
    std::bitset<6> index;//用于在S盒替换的索引
	for(size_t i = 0 ; i < 8 ; ++i)
	{//8个盒子
        index[0] = code[6 * i];
		index[1] = code[6 * i+1];
		index[2] = code[6 * i+2];
		index[3] = code[6 * i+3];
		index[4] = code[6 * i+4];
		index[5] = code[6 * i+5];
		std::bitset<4> temp(des_S[i][index.to_ulong()]) ;
		for(size_t j = 0 ; j < temp.size() ; j++)
			code[4 * i + j] = temp[j] ;//将32位暂存于48位中
	}
	for(size_t i = 0 ; i < pcode.size() ; i++)
		pcode[i] = code[des_P[i] - 1] ;//置换运算,P盒置换
	left ^= pcode ;//异或
	return 0 ;
}

int CDes::exchange(HBlock & left , HBlock & right)
{
    HBlock temp ;
	for(size_t i = 0 ; i < temp.size() ; i++)
		temp[i] = left[i] ;
	for(size_t i = 0 ; i < left.size() ; i++)
		left[i] = right[i] ;
	for(size_t i = 0 ; i < right.size() ; i++)
		right[i] = temp[i] ;
	return 0 ;
}

int CDes::final_replace(const HBlock & left , const HBlock & right , Block & block)
{
	for(size_t i = 0 ; i < block.size() ; i++)
	{
		if(pc_last[i] <= 32)
			block[i] = right[pc_last[i] - 1] ;//从right部分获取数据
		else
			block[i] = left[pc_last[i] - 32 - 1] ;//从left部分获取数据
	}
	return 0 ;
}

int CDes::Encry(Block & block , Block & bkey )
{
    HBlock left , right ;//左右部分
	ip(block , left , right) ;//初始置换
    genkey(bkey);//生成16轮子密钥
    for(int i = 0 ; i < SUBKEYNUM ; i++)//十六轮迭代	
    {	
        des_once(left , right , subkey[i]) ;
        if(i != (SUBKEYNUM-1)) //最后一次迭代完成后,左右俩个部分不进行交换
            exchange(left , right);
    }
    final_replace(left , right , block) ;//末置换
    return 0;
}

int CDes::Decry(Block & block , Block & bkey )
{
    HBlock left , right ;//左右部分
	ip(block , left , right) ;//初始置换
    genkey(bkey);//生成16轮子密钥
    for(int i = 15 ; i >= 0 ; i--)
    {
        des_once(left , right , subkey[i]) ;
        if(i != 0) //最后一次迭代完成后,左右俩个部分不进行交换
            exchange(left , right) ;
    }    
    final_replace(left , right , block) ;//末置换
    return 0;
}

CDes.h:

#pragma once

#include"commen.h"

#define SUBKEYNUM 16
typedef std::bitset<64> Block ;// 64 bits data block
typedef std::bitset<56> Key ;// 58 bits key
typedef std::bitset<48> Code ;// 48 bits data block 

typedef std::bitset<32> HBlock ;
typedef std::bitset<28> HKey ;
typedef std::bitset<24> HCode ;

class CDes
{
private:
    Code subkey[SUBKEYNUM]; //保存16轮迭代用到的子密钥
    int ip(const Block & block , HBlock & left , HBlock & right) ;//初始置换 IP
    int des_once(HBlock & left , HBlock & right , const Code & subkey) ;//一轮加/解密运算
    int exchange(HBlock & left , HBlock & right) ;//交换左右两个部分,辅助函数
    int final_replace(const HBlock & left , const HBlock & right , Block & block) ;//进行末置换 IP^-1
    int genkey(const Block & bkey) ;//产生16轮迭代用到的子密钥
public:
    // CDes();
    // ~CDes();
    int Encry(Block & block , Block & bkey );//封装一轮完整加密过程的函数
    int Decry(Block & block , Block & bkey );//封装一轮完整解密过程的函数
};

commen.h:

#pragma once
//some header files will be used
#include<iostream>
#include<bitset>
#include<cstring>
#include<thread>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/shm.h>
#include<mutex>
#include<string.h>

main.cpp:文章来源地址https://www.toymoban.com/news/detail-442708.html

#include"commen.h"
#include"CDes.h"


#define SERVER_PORT 7274
#define SERVER_IP "127.0.0.1"

using namespace std;

const int key_length = 9;
int c[90000];

//RSA加密函数
void encrypt(int e,int n){       //自己指定指数e

    //先将符号明文转换成字母所对应的ascii码。
    char plaintext[100];    //符号明文
    printf("Please enter the DES key:\n");
    scanf("%s",plaintext);
    int plain_ascii[strlen(plaintext)];   //定义符号明文
    for(int i=0;i<strlen(plaintext);i++){
        plain_ascii[i]=plaintext[i];        //将字母转换成对应的ascii码。
    }
    int ciphertext_figure=1;    //c为加密后的数字密文
    for(int i=0;i<strlen(plaintext);i++){

       for(int j=0;j<e;j++){
        ciphertext_figure=ciphertext_figure*plain_ascii[i]%n;
       }
       c[i]=ciphertext_figure;
       ciphertext_figure=1;
    }
    printf("The ciphertext is:\n");
       for(int i=0;i<strlen(plaintext);i++)
            printf("%d",c[i]);
        printf("\nEncryption ends, waiting for the ciphertext to be sent\n…………………………\n");



    //创建套接字
    int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    //将套接字和IP、端口绑定
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;  //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    serv_addr.sin_port = htons(1234);  //端口
    bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

    //进入监听状态,等待用户发起请求
    listen(serv_sock, 20);

    //接收客户端请求
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

    //向客户端发送数据

    write(clnt_sock, (char*)c, 90000);

    //关闭套接字
    close(clnt_sock);
    close(serv_sock);


    printf("\nThe key was sent successfully\n");
}

//RSA解密函数
void decrypto(int d,int n){

//创建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    //向服务器(特定的IP和端口)发起请求
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;  //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    serv_addr.sin_port = htons(1234);  //端口
    connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

    //读取服务器传回的数据
    read(sock, (char*)c, 90000);
    //关闭套接字
    close(sock);




    int de_plaintext[key_length],ciphertext_figure=1;
    char dePlaintext[key_length];
    for(int i=0;i<key_length;i++){

       for(int j=0;j<d;j++){
        ciphertext_figure=ciphertext_figure*c[i]%n;
       }
       de_plaintext[i]=ciphertext_figure;
       ciphertext_figure=1;
    }
    printf("The key is:\n");
    for(int i=0;i<key_length;i++){
        dePlaintext[i]=de_plaintext[i];
        printf("%c",dePlaintext[i]);
    }
    printf("\n…………………………\n");

}




void Block2Str(char * str , const Block & block)
{
	memset(str , 0 , 8) ;//将8个字节全部置0
    memcpy(str, &block, 8);
}

void Str2Block(Block & block , const char * str)
{
    memcpy(&block, str, 8);
}

struct packet
{
    bool isquit;
    char message[127];//单次发送信息不超过134字节
};

void recv_thread(int nsock, char* addr, char* key)
{
    char recv_buf[sizeof(packet)];
    Block bdata,bkey;
    CDes obj;
    packet pac;
    int n = sizeof(packet)/8;//packet的大小是8的整数倍

    Str2Block(bkey, key);

    while(1)
    {
        if(recv(nsock, recv_buf, sizeof(recv_buf), 0) < 0)
        {
            perror("接收信息失败");
            exit(errno);
        }

        for(int i=0;i<n;i++)
        {
            Str2Block(bdata, &recv_buf[i*8]);
            obj.Decry(bdata, bkey);
            Block2Str((char*)(&pac)+i*8, bdata);
        }

        if(pac.isquit)
        {
            cout<<"------------The chat ends------------"<<endl;
            send(nsock,  recv_buf, sizeof(recv_buf), 0);
            break;
        }
        else
        {
            printf("Receive message from <%s>: %s\n", addr, pac.message);
        }
    }
}

void send_thread(int nsock, char* key)
{
    char send_buf[sizeof(packet)];
    Block bdata,bkey;
    CDes obj;
    packet pac;
    pac.isquit  = false;
    bool isover = false;
    int n = sizeof(packet)/8;//packet的大小是8的整数倍

    Str2Block(bkey, key);

    while(!isover)
    {
        cin>>pac.message;
        if(strcmp(pac.message,"quit")==0)
        {
            isover = pac.isquit = true;
        }

        for(int i=0;i<n;i++)
        {
            Str2Block(bdata, (char*)(&pac)+i*8);
            obj.Encry(bdata,bkey);
            Block2Str(&send_buf[i*8],bdata);
        }
        if(send(nsock, send_buf, sizeof(send_buf),0) < 0)
        {
            perror("发送信息失败");
            exit(errno);
        }
    }
}

int main()
{
    int q,p,e,d,n,t;
    p = 17;
    q = 13;
    e = 7;
    n=q*p;
    t=(q-1)*(p-1);
    d = 55;

    char choose;
    cout<<"Client or Server?"<<endl;
    cin>>choose;
    if(choose == 'c')//client
    {
        decrypto(d,n);
        char key[9];

        int nConnectSocket;
        struct sockaddr_in sDestAddr;
        //1. 创建套接字
        if ((nConnectSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        {
            perror("Create socket failed!");
            exit(errno);
        }
        //2. 初始化sockaddr_in 结构体 sDestAddr
        sDestAddr.sin_family = AF_INET;
        sDestAddr.sin_port = htons(SERVER_PORT);
        sDestAddr.sin_addr.s_addr = inet_addr(SERVER_IP);
        //3. 与服务器建立连接
        if (connect(nConnectSocket, (struct sockaddr *) &sDestAddr, sizeof(sDestAddr)) != 0)
        {
            perror("Connect failed!");
            exit(errno);
        }
        else
        {
            printf("Connect Success! \nBegin to chat...\n");
            //4. 开始聊天
            /* blow matter */
            //5. 设定密钥
            cout<<"input the key:"<<endl;
            cin>>key;
            //6. 创建收发线程
            cout<<"-----------Communication begins-----------"<<endl;
            cout<<endl<<"   tip:Enter quit to exit the chat program"<<endl<<endl;

            thread sendt(send_thread, nConnectSocket, key);
            thread recvt(recv_thread, nConnectSocket, inet_ntoa(sDestAddr.sin_addr), key);
            recvt.join();
            sendt.join();
        }
        close(nConnectSocket);
    }
    else if(choose == 's')//server
    {
        encrypt(e,n);
        char key[9];
        struct sockaddr_in sLocalAddr, sRemoteAddr;
        int nListenSocket, nAcceptSocket;
        socklen_t nLength = sizeof(sRemoteAddr);
        //1. 建立本地套接字
        if ((nListenSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        {
            perror("Create socket failed!");
            exit(errno);
        }
        //2. 初始化sockaddr_in 结构体 sLocalAddr
        sLocalAddr.sin_family = AF_INET;
        sLocalAddr.sin_port = htons(SERVER_PORT);
        sLocalAddr.sin_addr.s_addr = inet_addr(SERVER_IP);
        //3. 绑定本地套接字
        if (bind(nListenSocket, (struct sockaddr *) &sLocalAddr, sizeof(struct sockaddr))== -1)
        {
            perror("bind failed!");
            exit(1);
        }
        //4. 开始监听
        if (listen(nListenSocket, 5) == -1)
        {
            perror("listen failed!");
            exit(1);
        }
        else{
            cout<<"Listening..."<<endl;
        }
        //5. 接受来自客户端的连接请求
        nAcceptSocket = accept(nListenSocket,(struct sockaddr *) &sRemoteAddr,&nLength);
        //6. 打印信息
        printf("server: got connection from %s, port %d, socket %d\n",inet_ntoa(sRemoteAddr.sin_addr),ntohs(sRemoteAddr.sin_port),nAcceptSocket);
        //7. 设定密钥
        cout << "input the key" << endl;
        cin >> key;
        //8. 开始聊天,创建收发线程
        cout<<"-----------Communication begins-----------"<<endl;
        cout<<endl<<"   tip:Enter quit to exit the chat program"<<endl<<endl;
        thread sendt(send_thread, nAcceptSocket, key);
        thread recvt(recv_thread, nAcceptSocket, inet_ntoa(sRemoteAddr.sin_addr), key);
        recvt.join();
        sendt.join();
        close(nListenSocket);
        close(nAcceptSocket);
    }
    return 0;
}

到了这里,关于一种DES和RSA混合加密的通信系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RSA+AES 混合加密

    非对称加密,使用公钥和私钥加密和解密,加密速度慢,公私钥分离安全性较高 具有以下特点: 安全性较高:RSA算法采用非对称加密方式,使用不同的公钥和私钥进行加密和解密,公钥用于加密,私钥用于解密,这种机制保证了加密数据的安全性。 适用性广泛:RSA算法广泛

    2024年02月04日
    浏览(40)
  • 常见加密解密(DES、RSA)以及摘要算法MD5的介绍

    1.1-理解MD5 MD5公开的算法,任何语言实现后其实都是一样的、通用的 不可逆加密:原文——加密——密文,密文无法解密出原文 1.2-MD5封装 1.3-MD5总结 相同原文加密的结果是一样的 不同长度的内容加密后都是32位,可以自行改变长度 原文件改动差别很小,结果差别很大 不管文

    2024年02月14日
    浏览(91)
  • RSA+AES实现混合加密

    为什么使用RSA + AES混合加密 1.加密介绍 RSA加密: 属于非对称加密,公钥用于对数据进行加密,私钥对数据进行解密,两者不可逆。公钥和私钥是同时生成的,且一一对应。比如:客户端拥有公钥,服务端拥有公钥和私钥。客户端将数据通过公钥进行加密后,发送密文给服务端

    2024年02月05日
    浏览(50)
  • C#集成数据加密算法,包含DES、RSA、Base64、SHA、MD5算法,轻松实现数据加密解密需求

    在需要使用配置文件的工控软件中,往往需要在配置文件和数据库中对一些数据加密,即对一串数据进行加密算法后输出复杂符号和字符的形式,让非相关人员无法识别原有数据,从而对数据或数据库进行相应的保护,这往往也是公司安全部门的基本要求。 网上写加密算法的

    2024年02月03日
    浏览(85)
  • 基于des双重加密算法的安全web电子邮件系统的设计与实现(论文+源码)_java_285

    摘要 本文首先研究并介绍国内外目前的背景和现状,在此基础上给出论文的主要研究内容,其次,对双重加密算法的电子邮件系统的需求进行了分析。再次,对双重加密算法的电子邮件系统进行了总体设计,根据其总体设计、软件架构和总体功能模块进行了详细设计,作出了

    2024年02月04日
    浏览(58)
  • 关于Triple DES(3DES)对称加密算法

    一、引言 在网络安全领域,对称加密算法作为一种常见的加密手段,被广泛应用于保障数据传输的保密性和完整性。其中,DES(Data Encryption Standard)算法作为一种经典的对称加密算法,由IBM于1970年代开发,并于1977年被美国国家标准与技术研究院(NIST)确定为联邦信息处理标

    2024年02月04日
    浏览(60)
  • go语言对称加密使用(DES、3DES、AES)

    进行DES、3DES、AES三种对称加密算法时,首先要对原始数据进行字节填充,使原始数据位数与所对应加密算法块数据量成倍数。 block cipher(分组密码、块密码) block size(块大小) DEA、3DES的block size为8位 AES的block size为16位 每个填充的字节都记录了填充的总字节数 \\\"a\\\" 填充后:

    2024年02月08日
    浏览(47)
  • 【密码算法 之一】对称加密算法 DES \ 3DES 浅析

      DES(Data Encryption Standard)是1977年美国联邦信息处理标准(FIPS)中所采用的一种对称密码(FIPS 46-3)。DES一直以来被美国以及其它国家的政府和银行等广泛使用。   然而,随着计算机的进步,现在DES已经能够被暴力破解,强度大不如从前了。20世纪末,RSA公司举办过破

    2024年02月09日
    浏览(57)
  • 【北京航空航天大学】【信息网络安全实验】【实验一、密码学:DES+RSA+MD5编程实验】

    1. 通过对DES算法的代码编写,了解分组密码算法的设计思想和分组密码算法工作模式; 2. 掌握RSA算法的基本原理以及素数判定中的Rabin-Miller测试原理、Montgomery快速模乘(模幂)算法,了解公钥加密体制的优缺点及其常见应用方式; 3. 掌握MD5算法的基本原理,了解其主要应用

    2024年02月19日
    浏览(52)
  • PHP 3DES加密

    不多说,直接上代码类 然后自行依据实际情况调用即可 自行了解引用,有测试示例在代码中 1. 2. 3. 4. 5. 6. 7.

    2024年02月13日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包