2020-1-7 爬网页18-js逆向入门(RSA加密-非对称加密,安全性高。pem,jsencrypt.min.js)

本文只适用于初学者,只需要会打断点追踪就可以了。

前端js代码除了Base64编码和解码,MD5加密,AES加密之外,有时候还会用RSA加密。

关于RSA加密详细说明,参见
https://blog.csdn.net/u014044812/article/details/80782448
https://blog.csdn.net/u014044812/article/details/80866759

简介

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。——维基百科

非对称算法有2个密钥,公钥和私钥。

1.加密和解密核心过程如下:

step1.用公钥 (n,e)加密
其中
e:Modulus,模数(系数)
n:Public exponent,指数

假设要一个字母m=“A”。
在通信传输中只能传输0和1,所以要先将“A”转ascii码为65,即m=65。m必须是整数(字符串可以取ascii值或unicode值),且m必须小于n。
通过以下加密公式算出密文c

密文c = 明文me(mod n)

表示:对明文m进行e次方后再对其用 n 求余,就得到了用RSA加密后的密文

由此,假设公钥为(n,e)=(3233, 17),明文m=65,那么密文c为

c = 6517(mod 3233)

所以,最终发送的密文就是2790

step2.用私钥(n,d)解密
接收方得到密文2790后,就用以下公式解密

明文m = 密文cd (mod n)

表示:将密文求 d 次方后再用 n 求余,就得到了原来的明文m。

此时接收方的私钥为 (n,d) = (3233,2753),明文为

m = 27902753 (mod 3233)

得到还原后的明文65,对应的字母就是A

2.整个RSA加解密过程如下:

  • 发送方获取到接收方的公钥 (n,e) = (3233,17)
  • 发送方选取发送的消息m=A=65。注意m要小于n,如果消息大于n,则可以分段加密!
  • 发送方过加密公式:c = me(mod n) 算出密文c=2790
  • 接收方获取到发送方的密文c=2790
  • 接收方利用自己的私钥 (n,d) = (3233,2753),使用解密公式:m = cd (mod n) 算出明文m=65=A

注意:RSA加密每次加密的结果是不一样的。具体原因参见链接

密钥生成

关于密钥和公钥的生成过程,参见链接

很多时候得到的公私钥是PEM格式,相关说明参见链接

例如

-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgGeDHRzMP9RAy7Xpxb/GW37uEXDF
HVYHZbJvu4OdO+TNGwdB9vLs1eWRlgkO740WyE9OO33PPNu4JOg0uXH6ehH+CUqM
SUHAeDmGGWYEMKB4IETl/c0c452tMKsm6kcxRUrnHleB0gJsNgW4czlomzpSUHLh
16HDJ7ZQ2r38k0nXAgMBAAE=
-----END PUBLIC KEY-----

这是标准的pem公钥格式,bytes类型,每64字符换一次行。

pem格式是可以转换为指数,模数格式 (n,e)的。
在线转换链接–>http://tool.chacuo.net/cryptrsakeyparse

js使用RSA加密

看个实际的例子
2020-1-7 爬网页18-js逆向入门(RSA加密-非对称加密,安全性高。pem,jsencrypt.min.js)_第1张图片
上面的网站,我输入的密码是123456,但是看form data,jxy_parameter中的password显然是加密了。

搜索"jxy_parameter",打上断点
2020-1-7 爬网页18-js逆向入门(RSA加密-非对称加密,安全性高。pem,jsencrypt.min.js)_第2张图片

先清空cookie,local storage和session storage。刷新网页后,开始追踪。
2020-1-7 爬网页18-js逆向入门(RSA加密-非对称加密,安全性高。pem,jsencrypt.min.js)_第3张图片

进去以后就会看到上面界面。
那个函数function O(e),就是典型的RSA加密。

function O(e) {
        var t = new JSEncrypt;
        return t.setPublicKey(e.key),
        function(n) {
            return t.encrypt(e.hash + n)
        }
    }

我们先说一下上图中下面的那个函数,它会产生一个post请求getkey。
可以看一下,它能获得下面的请求结果。
2020-1-7 爬网页18-js逆向入门(RSA加密-非对称加密,安全性高。pem,jsencrypt.min.js)_第4张图片
看到了什么,对了,就是public key公钥。
我们说过,RSA加密需要对方的公钥,所以在网页提交请求后,会先和服务器通讯,获得服务器公钥,然后再继续后面的提交请求步骤。

这个公钥值是不会变化的。你可以尝试多次,结果一样。

除了公钥,getkey请求还得到参数hash,这个值每次请求都会变。它和明文合并后再被加密。

t.encrypt(e.hash + n)

现在继续跟踪function O(e)
2020-1-7 爬网页18-js逆向入门(RSA加密-非对称加密,安全性高。pem,jsencrypt.min.js)_第5张图片
它会进入另外一个js文件,jsencrypt.min.js。
后面就不再展开,有兴趣自己继续跟踪。

我们来说明一下jsencrypt.min.js文件。
在这个文件中你可看到下面的文字

// Copyright (c) 2005-2009  Tom Wu
// All Rights Reserved.
// See "LICENSE" for details.

Tom Wu是什么人?你可以去链接中了解。
在链接的bin目录下,你也能找到那个熟悉的jsencrypt.min.js。

在js中使用RAS加解密方法,似乎都是使用了Tom Wu的jsencrypt.min.js。
斯坦福的链接中能看到Demo。

使用方法很简单。
先引入


然后加密

function 加密(公钥, 明文) { 
    var encrypt = new JSEncrypt();
    encrypt.setPublicKey(公钥);
    var 密文 = encrypt.encrypt(明文);
    return 密文
}

就和我们例子中展现的一致。

你可能感兴趣的:(python,js,IT)