写在前

最近在写一个模拟登陆腾讯企业邮箱的东西,但是发现在POST的数据中有一个p字段的内容是一个加密的字符串。经过查看源码发现p字段的值原来是由表单中pp和ts两个字段的值拼接并进行RSA加密的结果经过base64编码后得来的,其中pp字段是用户输入的密码,而ts字段是一个时间戳(在页面源码中已经给出)。最初的想法比较偷懒,想去直接调JS代码算出个结果返回回来,但是发现调这个JS太麻烦了,还不如直接用Python代码重新实现一遍这个加密算法呢……于是乎,折腾起来吧~

关于p值的来历

实现

首先,获取RSA算法的公钥和ts值很简单,直接从页面源码中按字符串处理的方式即可提取出公钥(当然,这里上个正则秀个操作也是可以的~),而ts的值从form表单中即可获取。

 

RSA算法的实现可以直接使用第三方库rsa,将加密后结果(十六进制)做base64编码即为所求的p值。

 

如果有细心的人验证结果是否正确时可能会发现我们算出来的p值和抓包抓到的提交的p值完全不同,但是不要慌,因为RSA算法在进行加密时会进行一个随机填充(而不是填充固定值,如全0),所以由于填充的值不同,我们算出来的结果与抓包看到的p值不同是正常的,不影响正常登录。

在提交完登录表单后会得到一个“重定向”的页面,这个页面里就包含了登陆进邮箱的地址targetUrl,并通过window.location.replace的方法将窗口“重定向”到了targetUrl。

登录成功后的返回结果

好了,任务完成~

前端加密在安全上的用途

了解安全的人都知道,明文传输登录表单是件很不安全的事情,因为我们无法保证数据在传输过程中的安全性,如果表单内容被嗅探,攻击者便可轻松直接拿到我们的帐号密码。对于这个问题一个比较好的解决办法就是启用HTTPS,使用HTTPS的安全性固然很高,但是由于其在经济、性能等方面都需要花费较大的成本,所以这种方案的应用并不十分普遍,而前端加密则是一种比较常见的替代方案,它通过前端JS对敏感数据加密然后再进行传输,可以很大程度上的减少资源的消耗。

下面以登录为例,我们来看一下通过前端加密传输密码的过程。

首先在我们请求登录页面的时候,服务器会将一个公钥(PublicKey)和一段用于加密的JS代码一起发给用户,在提交表单时浏览器会先执行这段JS代码对密码进行加密,然后将加密后的密码密文连通表单其他数据一起提交到服务器。这样数据包即使在传输过程中被嗅探到,但是由于没有私钥,攻击者仍然无法拿到真正的密码。

在此基础上,为了防止重放攻击等问题,服务器通常还会在用户请求登录页面的时候给用户发送一个盐值(salt),JS在进行加密时会将盐值和密码的明文一起加密。这样,由于每次的盐值不同所以每次加密后的密文也会不同,这样可以有效的避免重放攻击。

对于上面所提到的“用于加密的JS代码”的加密算要求是公钥加密算法,这样可以有效的防止攻击者解出密码的明文,一般多为RSA算法。

最后

虽然前端通过JS加密表单敏感数据的方法新浪微博、人人网等一些网站都在使用,但是目前网上关于这种方案的相关介绍还不是很多,所以如果您有这方面的资料或者经验可以分享的欢迎随时Email我,非常感激~

点击数:4589

2 thoughts on “Python实现模拟提交前端RSA加密数据的表单

  1. 版主,最近模拟登录某网站的时候,也是RSA加密。由于一个数字变量每次刷新页面都发生变化,导致我取数去生成密码的时候,再post,产生困难。查阅RSA资料的时候发现你有这方面的经验,能否指导一下。谢谢!

    1. 看了一下你提供的网站,里面tp参数目测是个时间戳(同文章中的ts参数),应该是为了避免相同的明文产生相同的密文而加的一个“随机数”,所以如果这样的话获取这个值你都不需要去从页面提取了对吧。

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据