前端的RSA长字段中文加密
love 2021-01-01
# 简述RSA算法
- RSA是目前使用最广泛的公钥密码体制之一,公钥可以公开,私钥保密,一般使用公钥加密,使用私钥解密,因为加密和解密使用不同的密码的方式,也被称为非对称加密
# 前端RSA加密库
- 最常用的是 JSEncrypt (opens new window),缺点不支持超长字符串加密,并且对中文加密支持度不够
# 改造
- 自行下载jsencrypt.js官网 (opens new window)
- 直接改动jsencrypt.js文件,在文件最下方的 JSEncrypt.version = “3.0.0-rc.1”;(截止本文写作时间时版本为此版本) 前面,添加下面的代码:
//任意长度RSA Key分段加密解密长字符串
//获取RSA key 长度
JSEncrypt.prototype.getkeylength = function () {
return ((this.key.n.bitLength()+7)>>3);
};
// 分段解密,支持中文
JSEncrypt.prototype.decryptUnicodeLong = function (string) {
var k = this.getKey();
//解密长度=key size.hex2b64结果是每字节每两字符,所以直接*2
var maxLength = ((k.n.bitLength()+7)>>3)*2;
try {
var hexString = b64tohex(string);
var decryptedString = "";
var rexStr=".{1," + maxLength + "}";
var rex =new RegExp(rexStr, 'g');
var subStrArray = hexString.match(rex);
if(subStrArray){
subStrArray.forEach(function (entry) {
decryptedString += k.decrypt(entry);
});
return decryptedString;
}
} catch (ex) {
return false;
}
};
// 分段加密,支持中文
JSEncrypt.prototype.encryptUnicodeLong = function (string) {
var k = this.getKey();
//根据key所能编码的最大长度来定分段长度。key size - 11:11字节随机padding使每次加密结果都不同。
var maxLength = ((k.n.bitLength()+7)>>3)-11;
try {
var subStr="", encryptedString = "";
var subStart = 0, subEnd=0;
var bitLen=0, tmpPoint=0;
for(var i = 0, len = string.length; i < len; i++){
//js 是使用 Unicode 编码的,每个字符所占用的字节数不同
var charCode = string.charCodeAt(i);
if(charCode <= 0x007f) {
bitLen += 1;
}else if(charCode <= 0x07ff){
bitLen += 2;
}else if(charCode <= 0xffff){
bitLen += 3;
}else{
bitLen += 4;
}
//字节数到达上限,获取子字符串加密并追加到总字符串后。更新下一个字符串起始位置及字节计算。
if(bitLen>maxLength){
subStr=string.substring(subStart,subEnd)
encryptedString += k.encrypt(subStr);
subStart=subEnd;
bitLen=bitLen-tmpPoint;
}else{
subEnd=i;
tmpPoint=bitLen;
}
}
subStr=string.substring(subStart,len)
encryptedString += k.encrypt(subStr);
return hex2b64(encryptedString);
} catch (ex) {
return false;
}
};
//添加的函数与方法结束
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 使用(jQuery)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>支持中文长字符串的RSA前端加解密代码</title>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="./jsencrypt.js"></script>
</head>
<body>
<div>
<label for="userdata">加密内容</label>
<br/>
<textarea id="userdata" rows="10" cols="100">汉皇重色思倾国,御宇多年求不得。杨家有女初长成,养在深闺人未识。
天生丽质难自弃,一朝选在君王侧。回眸一笑百媚生,六宫粉黛无颜色。
春寒赐浴华清池,温泉水滑洗凝脂。侍儿扶起娇无力,始是新承恩泽时。
云鬓花颜金步摇,芙蓉帐暖度春宵。春宵苦短日高起,从此君王不早朝。
承欢侍宴无闲暇,春从春游夜专夜。后宫佳丽三千人,三千宠爱在一身。
金屋妆成娇侍夜,玉楼宴罢醉和春。姊妹弟兄皆列土,可怜光彩生门户。
遂令天下父母心,不重生男重生女。骊宫高处入青云,仙乐风飘处处闻。
缓歌慢舞凝丝竹,尽日君王看不足。渔阳鼙鼓动地来,惊破霓裳羽衣曲。
九重城阙烟尘生,千乘万骑西南行。翠华摇摇行复止,西出都门百余里。
六军不发无奈何,宛转蛾眉马前死。花钿委地无人收,翠翘金雀玉搔头。
君王掩面救不得,回看血泪相和流。黄埃散漫风萧索,云栈萦纡登剑阁。
峨嵋山下少人行,旌旗无光日色薄。蜀江水碧蜀山青,圣主朝朝暮暮情。
行宫见月伤心色,夜雨闻铃肠断声。天旋地转回龙驭,到此踌躇不能去。
马嵬坡下泥土中,不见玉颜空死处。君臣相顾尽沾衣,东望都门信马归。
归来池苑皆依旧,太液芙蓉未央柳。芙蓉如面柳如眉,对此如何不泪垂。
春风桃李花开日,秋雨梧桐叶落时。西宫南内多秋草,落叶满阶红不扫。(花开日 一作:花开夜;南内 一作:南苑)
梨园弟子白发新,椒房阿监青娥老。夕殿萤飞思悄然,孤灯挑尽未成眠。
迟迟钟鼓初长夜,耿耿星河欲曙天。鸳鸯瓦冷霜华重,翡翠衾寒谁与共。
悠悠生死别经年,魂魄不曾来入梦。临邛道士鸿都客,能以精诚致魂魄。
为感君王辗转思,遂教方士殷勤觅。排空驭气奔如电,升天入地求之遍。
上穷碧落下黄泉,两处茫茫皆不见。忽闻海上有仙山,山在虚无缥渺间。
楼阁玲珑五云起,其中绰约多仙子。中有一人字太真,雪肤花貌参差是。
金阙西厢叩玉扃,转教小玉报双成。闻道汉家天子使,九华帐里梦魂惊。
揽衣推枕起徘徊,珠箔银屏迤逦开。云鬓半偏新睡觉,花冠不整下堂来。
风吹仙袂飘飖举,犹似霓裳羽衣舞。玉容寂寞泪阑干,梨花一枝春带雨。(阑 通:栏)
含情凝睇谢君王,一别音容两渺茫。昭阳殿里恩爱绝,蓬莱宫中日月长。
回头下望人寰处,不见长安见尘雾。惟将旧物表深情,钿合金钗寄将去。
钗留一股合一扇,钗擘黄金合分钿。但教心似金钿坚,天上人间会相见。
临别殷勤重寄词,词中有誓两心知。七月七日长生殿,夜半无人私语时。
在天愿作比翼鸟,在地愿为连理枝。天长地久有时尽,此恨绵绵无绝期。
</textarea>
<br/>
<label for="data">加密结果</label>
<br/>
<textarea type="text" id="data" rows="10" cols="100"></textarea>
<br/>
<label for="txt">解密结果</label>
<br/>
<textarea type="text" id="txt" rows="10" cols="100"></textarea>
<button id="testme" >加密与解密</button>
<br/>
<label for="privkey">私钥</label>
<br/>
<textarea id="privkey" rows="10" cols="100">-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDntgxoZuo4CdVc
BV516Cwqn5lg0siSPnwPKGW3O2NoGwdIzuB5sD3+0d/N5RC0kCgF8UmnMmwzMuAd
0P3A4q0HQhA9wPXfhLX2rilPSbXGRewcoBKhrLhVGIpgTdUkPHPT3Kn6KDNDY9U6
OeH65xz6YDk7dMO4c6jr6f/HWNykbK4kNhk8F1oBrw8mlSMlNnuEYlnAHpFzs8gI
BNbqNdcgaXG24t7Rbi/Uwg1JzXfEy4LJWGY8hDP6Hri1FlgtkyBkI4ekDUlg5Caj
soKhbcCK+Z0WieB4vj4ezIDEXZZlCt1cPcElLqm/Bfx9k3hWoYAuO7EHEHgHzc3Q
3/dIKsz7AgMBAAECggEBANvbONq3C/YwHmo6De8CZSXsWbQtTHK3Jy+avSinCSN2
weqroQLV330x1pGej8NEJTW+RIyIo3HRDCY+bwfeDR+d55swxBtZ6O4vQrMg1YFU
RzzCBeux3xWfO201bM/9LEoSTpY2Hq4Kw/+DfJB9Slmng6aOnEcgN1/hn/iesHyx
dCxeBfvcD6N+u8P3a0GgZ0p3im0QibPhErq7tp9oQh5D2xnFsJqlJz9w+ikDg+Vf
DG/oweccTQ5MF1h67VfypGboZTJZ5Mc+u/IUFxNjVMklNQ57XYEzfOzoEDQ4zO+T
47Wf9klT2tqv4d5Rvfnjfln5FtVHqxzInpZa7a+HZEECgYEA9zYMnrm2ubQkPFSx
+rjRbG2rYEkodVClK7cO7Ugk4leKH1+tpvGnit6M6I6gggK0jHZueo8YR+1x7p98
HTLF9HBrdcgQ6Gq9r3u/XLZ0bCnO+mgyeg8O8XtiuHosdD5WEWSTV5P2qJNkGxS5
UKP5nc7cVZXnnCbqT/ibnQ10ExcCgYEA7/LtsVZmxUHbc0QGd4cfXaAwL7BaoZHF
gHAfgNsDvkBNHqSqpyiSCkhHjBq6bSzRfvDHywHGNhvJhJtOp5X9LBw93aWU712d
tUzWGFnaxAJXAXONMtn8xOFw+Vg3yApx7RfkuSooaMnWp+FgrMV0kkDYMMxtZN4j
xBC+U0UiE70CgYBs/pCb3ufYgrtDOlhqYdg8BTJ9NmQ3LUJVvtU++wMAJHaKlKW8
qGklSjA4TMIp8EVodMMLGFItTFxiSEDxorQyrOpEONxzjLRrTZU2rF8yXVCbiRtQ
Q5lkEPGawosdCWrrKjvobh1ff/SwF/gIvPNOh6kPtxMx/tpqPgNmQEtAKwKBgEqU
hVDDfDn/mEghcqkgNJ2TNqb794+UkYC0WPZiHK27qrzFjc1bDNlpUeO4Qw3ACnWc
PV1Z9dPHm0E+TJpGQmS9enU0DDDCNkytzzXOZ/LYj1aCJfcSTkCbmdPGmb/xjyuU
a6Ep+1lmsvOHV9cboHn88bVpNO9PJGrCkYWsTUU5AoGAE2S2Zf5RlRICDd7H5/6y
bMzQUREnLIopUx1yNZSuLAOvsXq/wO1Utj/NTtZdJ0CRDhvUXipL7XK5p+sVVswV
BIXHeMYCML7XZXjPICE1EcMR57IxukbEpd+7p5i/deNshgYIHMSpYeRE6TdqXeT4
Ae3ypZCI0GPOGiMoLTJlySo=
-----END PRIVATE KEY-----</textarea>
<br/>
<label for="pubkey">公钥</label>
<br/>
<textarea id="pubkey" rows="10" cols="100">-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA57YMaGbqOAnVXAVedegs
Kp+ZYNLIkj58DyhltztjaBsHSM7gebA9/tHfzeUQtJAoBfFJpzJsMzLgHdD9wOKt
B0IQPcD134S19q4pT0m1xkXsHKASoay4VRiKYE3VJDxz09yp+igzQ2PVOjnh+ucc
+mA5O3TDuHOo6+n/x1jcpGyuJDYZPBdaAa8PJpUjJTZ7hGJZwB6Rc7PICATW6jXX
IGlxtuLe0W4v1MINSc13xMuCyVhmPIQz+h64tRZYLZMgZCOHpA1JYOQmo7KCoW3A
ivmdFongeL4+HsyAxF2WZQrdXD3BJS6pvwX8fZN4VqGALjuxBxB4B83N0N/3SCrM
+wIDAQAB
-----END PUBLIC KEY-----</textarea>
<br/>
</div>
<script type="text/javascript">
$(function() {
$('#testme').click(function() {
var encrypt = new JSEncrypt();
encrypt.setKey($('#pubkey').val());
console.log(encrypt.getkeylength());
var data = encrypt.encryptUnicodeLong($('#userdata').val());
$('#data').val(data);
var decrypt = new JSEncrypt();
decrypt.setKey($('#privkey').val());
var txt = decrypt.decryptUnicodeLong(data);
$('#txt').val(txt);
});
});
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150