Python技能包:基于RSA+MD5+DH+TDES的轻量级加密通信系统

资源

RSA原理
RSA+MD5签名验证
MD5_Python
RSA_Python
Python实现RSA+MD5
Diffie-Hellman原理
DH密钥协商算法
GayHub_pyDHE
FREEBUF_pyDHE

第三方库安装

pip3 install pycryptodome

在使用的时候导入此模块是有问题的,这个时候要修改一个文件夹的名称
Python安装目录\Lib\site-packages
找到这个路径,下面有一个文件夹叫做crypto,将小写c改成大写C就ok了.

pip3 install pyDHE

RSA

Alice有公钥 PublicA = (EncryA, NumA)
私钥 PrivateA = (DecryA, NumA)

Bob有公钥 PublicB = (EncryB, NumB)
私钥 PrivateB = (DecryB, NumB)

双方互相知道对方的公钥

签名
Alice生成一个随机数random
用自己的私钥 PrivateArandom生成签名 RSA(PrivateA, random)
然后把签名和随机数random给Bob发过去
Bob收到后用Alice的公钥 PublicA 对签名进行验签得到签名中的random
如果签名中的random与一同发送来的随机数random一样
则证明消息是Alice发过来的

加密+签名
Alice生成一个随机数random
Bob的公钥PublicB先进行一次加密生成密文RSA(PublicB, random)
用自己的私钥 PrivateA 和 密文生成签名 RSA(PrivateA, RSA(PublicB, random))
然后把签名和随机数random给Bob发过去
Bob收到后用Alice的公钥 PublicA 进行验签
得到密文RSA(PublicB,random)
然后Bob用自己的私钥PrivateB对密文进行解密得到签名中的random
如果验签结果与一同发送来的随机数random一样
则证明消息是Alice发过来的

MD5

MD5算法的原理可简要的叙述为:MD5码以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

RSA+MD5

签名
不是对随机数random签名,而是对随机数的MD5值签名
验签时是看签名中的MD5值是否与校验信息作MD5运算后的值相等

Diffie-Hellman

客户端Alice和服务器Bob希望有一个相同的共享密钥以进行后续基于对称加密算法的安全会话
所以采用DH密钥协商算法
流程
Alice与Bob共享一个素数p以及该素数的本原根g

客户端Alice选一个随机数PrivateA作为私钥( 1 ⩽ PrivateA ⩽ p−1 )
通过计算得到一个公钥PublicA

服务器Bob选一个随机数PrivateB作为私钥( 1 ⩽ PrivateB ⩽ p−1 )
通过计算得到一个公钥PublicB

双方通过公网交换公钥

此时Alice知道的信息有

自己的私钥:PrivateA
自己的公钥:PublicA
Bob的公钥:PublicB

Bob同理

Alice计算共享密钥KeyA : KeyA = (PublicB) ^ PrivateA mod p
Bob计算共享密钥KeyB: KeyB = (PublicA) ^ PrivateB mod p
可证得:KeyA = KeyB 统一用key表示
这样双方就得到了同一个共享密钥key

注意:安全性问题不作深究

TripleDES

3DES算法是指使用双长度(16字节)密钥K=(KL||KR)
将8字节明文数据块进行3次DES加密/解密。
Y = DES( KL[DES-1( KR[DES( KL[X] )] )] )

解密方式
X = DES-1( KL[DES( KR[DES-1( KL[Y] )] )] )
其中,DES( KL[X] )表示用密钥K对数据X进行DES加密,DES-1( KR[Y] )表示用密钥K对数据Y进行解密。
SessionKey的计算采用3DES算法,计算出单倍长度的密钥。表示法为:SK = Session(DK,DATA)

加密方式
VOID 3DES(BYTE DoubleKeyStr[16], BYTE Data[8], BYTE Out[8])
{
BYTE Buf1[8], Buf2[8];
DES (&DoubleKeyStr[0], Data, Buf1);
UDES(&DoubleKeyStr[8], Buf1, Buf2);
DES (&DoubleKeyStr[0], Buf2, Out);
}

pyDHE详解

  1. 创建DHE对象 Alice
Alice = pyDHE.new()

可选参数为14~18, 不写的话默认14(参数范围存疑)
看源码这个参数的作用应该是用来生成大素数p的
贴一个参数为默认值14时生成的p

3231700607131100730033891392642382824881794124114023911284200975140074170663435422261968941736
3569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078
2362488842461894775876411059286460994117232454266225221932305409190376805242355191256797158701
1700105805587765103886184728025797605490356973256152616708133936179954133647655916036831789672
9073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988
5885653692086452966360772502689555059283627511211740969729980684105543595848665832916421362182
31078990999448652468262416972035911852507045361090559

factordb验证一下
在这里插入图片描述果然是素数
在这里插入图片描述
2. Alice的各项属性

Alice.p # 素数p
Alice.g # 本原根g
Alice.a # Alice的私钥
Alice.group # 传入参数,根据命名来看应该是分组
Alice.key # 与Bob协商后生成的共享密钥key
  1. Alice的各项方法
Alice.getPublicKey() #返回值为int型 Alice的公钥
Alice.update(PublicB) # 传入Bob的公钥,计算共享密钥并返回
Alice.getFinalKey() #返回与Bob协商后的共享密钥key

一个示例

import pyDHE
Alice = pyDHE.new(14)
Bob = pyDHE.new(14)
aliceFinal = Alice.update(Bob.getPublicKey())
bobFinal = Bob.update(Alice.getPublicKey())
print(aliceFinal == bobFinal)
# 结果为 True

协商错误示例

import pyDHE
Alice = pyDHE.new(14)
Bob = pyDHE.new(15)
# 传入参数值必须相同,否则不在一个组内无法协商出相同的共享密钥
aliceFinal = Alice.update(Bob.getPublicKey())
bobFinal = Bob.update(Alice.getPublicKey())
print(aliceFinal == bobFinal)
# 结果为 False

socket通信

对socket通信还不熟悉的可以看我的博客
DDOS:从socket通信开始

代码实现

GayHub:EncryptedCommunicateSystem
在这里插入图片描述

(黄色叹号标志是PEP8规范的警告,非代码警告)

一个旁路模块 RSA_Generator用于生成RSA公私钥对
两个底层模块 RSA_SVED、TripleDES用于向中层模块提供原始的密码学方法(签名、验签、加密、解密等)
两个中层模块 UniversalMethods封装了底层模块的原始方法,与socket通信结合,可以被上层模块直接调用。DiffieHellman操作比较简单,直接被顶层模块调用
两个顶层模块 AliceClient和BobServer,也是最后运行的主模块。考虑到客户端与服务器各自的socket操作(绑定、监听、连接、关闭等)不同,方法不能共用,所以将各自的socket方法定义在顶层模块

调用关系图
在这里插入图片描述
通信流程

  1. 由RSA_Generator生成两对公私钥,由于是轻量级身份认证系统不涉及PKI的使用,所以直接以pem文件的格式将公钥下发给对方
  2. BobServer启动,监听9999端口,等待客户端连接
  3. 客户端连接到服务器后,生成一个四位随机数,把随机数用服务器的RSA公钥加密生成RSA密文,然后用自己的私钥对RSA密文的MD5值签名,把时间戳、签名、RSA密文(校验信息)发送给服务器
  4. 服务器端同上
  5. 服务器接收到数据包后,校验时间戳,用对方的公钥解签,得到签名中的密文的MD5值,然后对校验信息作MD5运算,如果两个MD5值相等,则说明客户端合法,否则关闭连接
  6. 客户端同上
  7. 双向认证通过后开始用Diffie-Hellman算法协商共享密钥。客户端将自己的DH_Group参数用服务器RSA公钥加密,对密文的MD5签名,把时间戳、签名、RSA密文(校验信息)发给服务器
  8. 服务器收到后校验时间戳,验签后用自己的RSA私钥解密RSA密文,得到DH_Group,然后用相同的DH_Group生成服务器DH公私钥
  9. 客户端把自己的DH公钥明文发送给服务器,服务器接收到后作运算,生成一个共享DH密钥
  10. 服务器把自己的DH公钥明文发送给客户端,客户端接收到后作运算,生成一个共享DH密钥
  11. 因为双方的DH对象使用了同一个DH_Group参数,那么生成的两个共享DH密钥是相等的
  12. 使用共享DH密钥作TripleDES的加解密密钥,开始通信
  13. 双方启动多线程,一边发送,一边监听
  14. 发送线程:客户端输入英文,进行TDES加密,然后用服务器RSA公钥进行RSA加密,再用客户端RSA私钥RSA密文的MD5值签名,将时间戳,签名,RSA密文(校验信息)打包发给服务器
  15. 监听线程:服务器收到后校验时间戳,然后用客户端的RSA公钥验签,验签成功后进行TDES解密,得到明文
  16. 服务器同上
  17. 客户端发送线程输入WMend,结束发送线程,服务器得到明文为WMend后,结束监听线程。
  18. 服务器发送线程输入WMend,结束发送线程,客户端得到明文为WMend后,结束监听线程
  19. 通信结束

通信示例

时间戳的用法有误
开始的合法性校验应该是三次握手而非两次
待改
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

发布了61 篇原创文章 · 获赞 11 · 访问量 4875

猜你喜欢

转载自blog.csdn.net/weixin_43249758/article/details/103518993