-
-
[翻译]加密聊天室:第二部分
-
发表于:
2018-7-17 22:21
4715
-
(前段时间忙于毕业,接手了这篇翻译一直就搁在那,今天逛论坛发现组内小姐姐已经将第一部分翻译出来,阅读之后觉得这个工程量不大加之作者的构思很是清晰,可以锻炼一下自己的Python代码能力,并且其中的关于DH的操作考虑的还是非常周到的,故翻译出来供大家阅读学习)
原文链接:https://0x00sec.org/t/encrypted-chat-part-ii/5958
在了解加密聊天服务器背后的概念之后,我们已经做好准备来近距离的查看代码来理解服务器和客户端是怎样操作的
下面是本次加密聊天项目的文件组成:
服务端和客户端公用许多的代码,特别是关于消息加密解密的代码。然而,由于是服务端进行大部分的处理,我们将会从服务端的代码开始。
这里我只会讨论关键的代码,而省略一些琐碎的代码。完整的代码可以在这里找到。
server.py:
首先我们创建一个服务端用来交互的套接字:
接着,使用m2crypto里的DH模块我们生成一个用来做DH秘钥交换的参数:
请记住,我们需要创建两个公共值:素数模p和素数基g。当我们指定所需素数的大小(以位为单位)(建议公钥素数至少为2048位)以及我们想要使用哪个生成器时,此函数返回包含p和g的类。它使用OpenSSL库,“是用于传输层安全性(TLS)和安全套接字层(SSL)协议,商业级的的强大全功能工具包”以及“通用加密库”。许多其他程序使用此库,例如OpenVPN。
现在我们可以等待新客户端连接,当有连接尝试时使用Diffie-Hellman密钥交换并监听其传入的加密消息。
我们使用套接字接受下一个传入连接(此功能阻塞)并将其初始化为新客户端。 让我们来看看这样做时会发生什么:
客户端类接收服务器(客户端所属的服务器),套接字连接和格式(ip_address,port)的地址。然后调用dh()来生成共享密钥。
首先,使用位于dhke.py中的DH.b2i方法将p和g参数从字节转换为整数。然后它生成一个随机私钥a(也是一个整数)。此交换的服务器公钥是通过将g增加到a的幂并使用DH.gen_public_key()将结果取模p来计算。
现在,它可以使用值p,g和public_key来构造要发送到客户端的公共消息。
**注意:客户端需要这三个值来生成自己的公钥
以下行创建一个新的DH对象并将其转换为字节:
我们可以看到在DH的bytes方法中如何将三个变量编码为字节:
由于我们需要一个标准化的消息格式供客户端解包,因此我们设置格式为前1024个字节属于p,后面是16到g,最后1024个属于公钥。 package方法只是将整数变量转换为字节并添加填充,直到它达到所需的长度:
将消息全部打包后,我们将其发送到客户端并等待客户端携带公钥的响应:
然后我们将响应从字节转换为整数,并使用我们自己的私钥a和共享素数p将其传递给DH.get_shared_key()方法:
get_shared_key()计算(client_key ^ a)%p,将结果转换为十六进制字符串,并将其传递给sha256以标准化其长度:
最后,我们生成了一个共享密钥!这很酷,但当然在实践中它比理论上要复杂一些。现在,我们到哪一步了?
在声明了密钥后,我们就已经完成了服务器内的客户端初始化。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2018-7-18 15:57
被wangring编辑
,原因: