本文只适用于初学者,只需要会打断点追踪就可以了。
前端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加密
看个实际的例子
上面的网站,我输入的密码是123456,但是看form data,jxy_parameter中的password显然是加密了。
搜索"jxy_parameter",打上断点
先清空COOKIE,local storage和session storage。刷新网页后,开始追踪。
进去以后就会看到上面界面。
那个函数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。
可以看一下,它能获得下面的请求结果。
看到了什么,对了,就是public key公钥。
我们说过,RSA加密需要对方的公钥,所以在网页提交请求后,会先和服务器通讯,获得服务器公钥,然后再继续后面的提交请求步骤。
这个公钥值是不会变化的。你可以尝试多次,结果一样。
除了公钥,getkey请求还得到参数hash,这个值每次请求都会变。它和明文合并后再被加密。
t.encrypt(e.hash + n)
现在继续跟踪function O(e)
它会进入另外一个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 密文
}
就和我们例子中展现的一致。