javascript使用RSA加密提交数据
来源:互联网 发布:informix 端口 编辑:程序博客网 时间:2024/06/06 04:08
场景:出于安全考虑,要求对页面提交的关键信息进行加密,在网络传输过程中使用密文传递,在服务器端解密后使用。这样不管在浏览器端还是网络传输中截获了数据,都无法获取实际的信息。
方法:使用非对称加密算法,在页面端使用公钥进行加密,在服务器端使用密钥进行解密。
已经有人通过javascript实现了rsa加密算法,以下是两个选择:
1、http://www.ohdave.com/rsa/
该版本不支持非ASCII的字符。
相同数据每次加密后的密文是固定的,使用标准的RSA算法解密后就可以获得加密前的数据。
2、http://www-cs-students.stanford.edu/~tjw/jsbn/
该版本支持UTF-8可以编码的所有字符,包括中文。
相同数据每次加密后的密文是变化的,使用标准的RSA算法解密后还需要进行处理后才能获得加密前的数据。
该网站还给出了一个供参考的性能比较结果:
http://www-cs-students.stanford.edu/~tjw/jsbn/speed.html
下面分析下两个版本不同的原因:
http://www-cs-students.stanford.edu/~tjw/jsbn/rsa.js
在于这个js中的这个方法:
- // PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
- function pkcs1pad2(s,n) {
- if(n < s.length + 11) { // TODO: fix for utf-8
- alert("Message too long for RSA");
- return null;
- }
- var ba = new Array();
- var i = s.length - 1;
- while(i >= 0 && n > 0) {
- var c = s.charCodeAt(i--);
- //UTF-8编码为变长字节,使用实际的字节来记录
- if(c < 128) { // encode using utf-8
- ba[--n] = c;
- }
- else if((c > 127) && (c < 2048)) {
- ba[--n] = (c & 63) | 128;
- ba[--n] = (c >> 6) | 192;
- }
- else {
- ba[--n] = (c & 63) | 128;
- ba[--n] = ((c >> 6) & 63) | 128;
- ba[--n] = (c >> 12) | 224;
- }
- }
- //实际输入拼装结束,将下一位赋值为0标记结束
- ba[--n] = 0;
- var rng = new SecureRandom();
- var x = new Array();
- //拼接随机非0字节
- while(n > 2) { // random non-zero pad
- x[0] = 0;
- while(x[0] == 0) rng.nextBytes(x);
- ba[--n] = x[0];
- }
- //这两位做简单的校验
- ba[--n] = 2;
- ba[--n] = 0;
- return new BigInteger(ba);
- }
该方法中对UTF-8字符进行了兼容,并且在拼装完实际输入的字符后,还拼装了随机的字节,使用拼装后的字符串去加密。由于每次拼装的结果是随机的,这样每次加密后的密文都不同。
解密后,按照加密时标记的结束位标志,截取出实际的输入即可。
下面是通过javascript解密的代码,服务器端解密后的处理同理。
http://www-cs-students.stanford.edu/~tjw/jsbn/rsa2.js
- // Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
- function pkcs1unpad2(d,n) {
- var b = d.toByteArray();
- var i = 0;
- while(i < b.length && b[i] == 0) ++i;
- if(b.length-i != n-1 || b[i] != 2)
- return null;
- ++i;
- while(b[i] != 0)
- if(++i >= b.length) return null;
- var ret = "";
- while(++i < b.length) {
- var c = b[i] & 255;
- if(c < 128) { // utf-8 decode
- ret += String.fromCharCode(c);
- }
- else if((c > 191) && (c < 224)) {
- ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));
- ++i;
- }
- else {
- ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));
- i += 2;
- }
- }
- return ret;
- }
由于js加密中使用的是RSA的NOPADDING的填充模式,使用SUN虚拟机默认的RSA解密算法解密会报错,可以使用第3方的算法提供程序。
服务器端解密代码及完整例子参见RSA使用js加密,使用java解密
- javascript使用RSA加密提交数据
- 使用RSA算法加密数据
- JAVA使用RSA加密数据
- RSA使用javascript加密JAVA解密
- 使用DES和RSA做数据加密
- java使用RSA加密方式实现数据加密解密
- 数据加密--RSA
- RSA 数据加密解密
- 25、数据加密-RSA
- 使用openssl库实现RSA、AES数据加密
- 使用openssl库实现RSA、AES数据加密
- 使用openssl库实现RSA、AES数据加密
- iOS中使用RSA对数据进行加密解密
- 使用openssl库实现RSA、AES数据加密
- iOS中使用RSA对数据进行加密解密
- iOS中使用RSA对数据进行加密解密
- iOS中使用RSA对数据进行加密解密
- iOS中使用RSA对数据进行加密解密
- android学习笔记(十二)日期、时间组件
- zoj 3717 二分+2sat tarjan求强连通
- Fedora和Ubuntu指令差别(待补充)
- extjs 定义类
- JNI(2) Android NDK 环境搭建与使用
- javascript使用RSA加密提交数据
- C#-控制台-希尔排序法---ShinePans
- Openstack Glance Image状态迁移-Havana
- make Image uImage与zImage的区别
- 输入/输出流体系
- 我的vim配置笔记
- 黑马程序员--银行调度系统
- hdu 1698 Just a Hook 线段树 成段更新
- RabbitMQ