基于Python使用RSA算法进行签名

安全的代理

加密方法:

借助python的pycrypto库,使用公/私钥RSA加密和AES对称会话密钥加密,使用RSA算法进行签名。

具体实现:

事先生成好两对RSA公钥和密钥,分别保存在客户端和服务端本地,AES会话密钥由双方沟通确定。定义AESUtil类和RsaUtil类,用来保存各自的密钥和执行加密操作。对于要加密的bytes流,先用SHA256取出摘要,然后使用本地的RSA私钥进行签名,把签名后的结果接在bytes流后面。再对整体使用远端的公钥进行Rsa加密,对得到的结果再使用会话密钥进行AES加密后发出。对于要解密的bytes流,先用会话密钥进行第一次解密,再用本地的RSA私钥进行第二次解密,由于签名的长度是确定的,可以确定得到的结果的后128位是签名,前面的部分是传输内容。然后使用远端的公钥验签,认证不成功则报错。如上的签名过程可以确保数据的完整性。

RSA加密要求明文长度不能超过某个特定值,解决办法是定义public_long_encrypt函数,将待加密数据分段后分别加密再接到一起,解密同理分段进行。这里需要注意的是明文和密文的长度关系,分段的时候长度必须对应。

AES加密要求明文长度必须是{16, 24, 32}之一的倍数。本项目中以16为基数。对于长度不满足条件的串,用padding字符补足到只差一位,再在最后一位记录补足的个数。对于长度是16的整数倍的串,补上15个padding字符后再最后一位记录好16。解密时读出最后一位的数字,把后面对应的位抛弃掉即可。

网络设计:

使用了开源项目Lightsocks的Python版本Lightsocks-Python中网络框架的部分,主要做法是用python中的asyncio库来高效地实现协程的调度:

  • 先用TCP监听固定的端口(客户端是浏览器代理127.0.0.1:1080,服务器则是0.0.0.0:8388,后者端口可自己设置);
  • 选取完成三次握手的连接,进行socks5协议的通信,来由客户端代理告诉服务器真正的访问地址;
  • 服务器与真正的访问地址建立连接后,就可以形成一条完成的链路:浏览器-客户端-服务端-真正的访问地址的通路,然后浏览器到客户端以及服务端到真正的访问地址的通信是正常访问,而客户端和服务端则采用了上面提到的加密算法进行通信。然后两者不断转发数据即可。

实验结果:

从控制台输出可以看出,双方进行了大量的数据交换。但在Chrome浏览器中配置好代理设置后,只能很不稳定地加载出网页内容。其中对于微博网页weibo.com,浏览器可以比较稳定地加载出网站证书,但不能显示网页内容。加密算法经本地测试并无错误,但我们没能找到网页不能稳定显示的原因。

在这里插入图片描述

客户端控制台输出示例:
在这里插入图片描述

服务端控制台输出示例:
在这里插入图片描述


update:

  • 在去除AES加密算法之后,发现可以访问Google网站了,但是响应速度较慢。具体原因未知。
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值