RSA算法使用javascript加密,使用java解密,提供完整代码及例子下载。

javascript加密介绍参见另一篇:javascript使用RSA加密提交数据。本篇的例子使用的js是上一篇中提到的第2个版本。

本篇是服务端解密部分,并且提供可运行的包括js的全部示例代码。

由于sun虚拟机自带的RSA解密填充模式使用的都是特殊的PADDING模式,而js中使用的padding其实就是特殊处理的部分,实际加密时是nopadding模式,所以无法直接使用sun自带的RSA算法在服务器端解密,可以使用第3方bouncycastle提供的算法程序,最新版可以在这里下载http://www.bouncycastle.org/latest_releases.html

update:

测试时,请使用java中输出的js公钥替换test.html中的公钥。

关于性能:

第一次解密过程相对来说比较慢(几百毫秒),后续的过程都比较快,可以通过多条值测试。

关于并发:

可以通过使用多个值解密,循环创建线程来测试并发时的正确性和耗费时间。

使用过程中注意到的问题:

密钥对的值与种子、虚拟机实现等都有关系,不同的机器生成的密钥值可能不同。在实际测试时发现,同样的环境,有些机器每次生成的密钥值也不同,比如每次重启服务器后值不同。所以在实际生产环境中使用时,该值需要通过服务器端输出到客户端。如果有多台服务器,可能每台服务器的值不同,所以需要有类似F5的策略,保证多次请求路由到一台服务器上。

或者所有服务器都通过读取提前生成的证书或者私钥串来生成私钥对象,然后再进行解密。

package com.yajiao.rsa;

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.PrivateKey;

import java.security.Provider;

import java.security.PublicKey;

import java.security.SecureRandom;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import org.bouncycastle.jce.provider.JCERSAPublicKey;

import org.bouncycastle.util.encoders.Base64;

import org.bouncycastle.util.encoders.Hex;

public class RSABCExample {

/** 可以先注册到虚拟机中,再通过名称使用;也可以不注册,直接传入使用 */

public static final Provider pro = new BouncyCastleProvider();

/** 种子,改变后,生成的密钥对会发生变化 */

private static final String seedKey = "random";

private static final String charSet = "UTF-8";

//private static String publicKeyStr = null;

//private static String privateKeyStr = null;

private static PrivateKey privateKey = null;

private static PublicKey publicKey = null;

private static String jsPublicKey = null;

static{

try {

generateKeyPair();

getJsPublicKey();

} catch (Exception e) {

throw new RuntimeException("生成密钥对失败");

}

}

/**

* 生成密钥对

* @throws Exception

*/

private static void generateKeyPair() throws Exception {

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", pro);

kpg.initialize(1024, new SecureRandom(seedKey.getBytes()));

KeyPair kp = kpg.generateKeyPair();

privateKey = kp.getPrivate();

publicKey = kp.getPublic();

//privateKeyStr = new String(Base64.encode(privateKey.getEncoded()));

//publicKeyStr = new String(Base64.encode(publicKey.getEncoded()));

//System.out.println("PrivateKey:" + privateKey);

//System.out.println("PublicKey:" + publicKey);

//System.out.println(privateKeyStr);

//System.out.println(publicKeyStr);

}

/**

* 解密

*/

public static byte[] decrypt(byte[] encrypted) throws Exception {

long start = System.currentTimeMillis();

Cipher cipher = Cipher.getInstance("RSA", pro);

cipher.init(Cipher.DECRYPT_MODE, privateKey);

byte[] re = cipher.doFinal(encrypted);

long end = System.currentTimeMillis();

System.out.println("decrypt use time " + (end - start) + "");

return re;

}

/**

* 解密js加密后的值

*/

public static String decodeJsValue(String jsValue) throws Exception {

byte[] input = Hex.decode(jsValue);

byte[] raw = decrypt(input);

// 标志位为0之后的是输入的有效字节

int i = raw.length - 1;

while (i > 0 && raw[i] != 0) {

i--;

}

i++;

byte[] data = new byte[raw.length - i];

for (int j = i; j < raw.length; j++) {

data[j - i] = raw[j];

}

return new String(data, charSet);

}

/**

* js加密时使用的公钥字符串

*

注意:

* 生成的密钥对的值与 种子(seedKey)、虚拟机实现等都有关系,不同的机器生成的密钥值可能不同。

* 在实际测试时发现,同样的环境,有些机器每次生成的密钥值也不同,比如每次重启服务器后值不同。

* 所以在实际生产环境中使用时,该值需要通过服务器端输出到客户端。

* 如果有多台服务器,可能每台服务器的值不同,所以需要有类似F5的策略,保证多次请求路由到一台服务器上。

*/

public static String getJsPublicKey(){

if(jsPublicKey == null){

JCERSAPublicKey jce = (JCERSAPublicKey) publicKey;

jsPublicKey = jce.getModulus().toString(16);

}

return jsPublicKey;

}

public static void main(String[] args) throws Exception {

//注意:需要使用该值替换test.html中的公钥值

System.out.println("js中使用的公钥字符串" + getJsPublicKey());

// js加密后的值

String de = "08f7e292ccb4c73a981569a9c2dbf2b9c0c2cf615967282863e6e358432af288f1f026ed91a8ff5f6579ac246af9ce1f94f85e92b8a926627b95e6bd05b00b80a5548e9ce1a9bb2a20073cce629936ab9e27021af7370c2664065107a702c1805a4ec131a3573007213da3e390221053867074a427ffc28aa642fe2099ad7332";

System.out.println(decodeJsValue(de));

}

//-------------------------下面方法可以不用

private void test(){

// check equals

//PublicKey pb = getPublicRSAKey(publicKeyStr);

//System.out.println(pb.equals(publicKey));

//PrivateKey ppk = getPrivateRSAKey(privateKeyStr);

//System.out.println(ppk.equals(privateKey));

//

//String input = "测试abcABC123";

//byte[] en = encrypt(input);

//System.out.println(new String(Hex.encode(en)));

//

//byte[] re = decrypt(en);

//System.out.println(new String(re, charSet));

}

/**

* 根据Base64编码的公钥值生成公钥对象

*

* 测试时使用,可以用于从证书文件中的公钥生成公钥对象。如果不涉及到证书操作,可以忽略该方法。

*/

public static PublicKey getPublicRSAKey(String key) throws Exception {

X509EncodedKeySpec x509 = new X509EncodedKeySpec(Base64.decode(key));

KeyFactory kf = KeyFactory.getInstance("RSA", pro);

return kf.generatePublic(x509);

}

/**

* 根据Base64编码的私钥值生成私钥对象

*

* 测试时使用,可以用于从证书文件中的私钥生成私钥对象。如果不涉及到证书操作,可以忽略该方法。

*/

public static PrivateKey getPrivateRSAKey(String key) throws Exception {

PKCS8EncodedKeySpec pkgs8 = new PKCS8EncodedKeySpec(Base64.decode(key));

KeyFactory kf = KeyFactory.getInstance("RSA", pro);

return kf.generatePrivate(pkgs8);

}

/**

* 加密

*/

public static byte[] encrypt(String input) throws Exception {

long start = System.currentTimeMillis();

Cipher cipher = Cipher.getInstance("RSA", pro);

cipher.init(Cipher.ENCRYPT_MODE, publicKey);

byte[] re = cipher.doFinal(input.getBytes(charSet));

long end = System.currentTimeMillis();

System.out.println("encrypt use time " + (end - start) + "");

return re;

}

}

js rsa java解密_RSA使用js加密,使用java解密相关推荐

  1. java程序jar包xjar加密及破解解密

    背景 项目要部署到第三方服务器上,于是研究了一下jar包加密的方式,其中在github上有一个项目XJar,挺多使用用户,也搜到了破解的教程,于是研究了一下.详细说下如何加密.破解.这些加密只能说&q ...

  2. 用户密码的加密解密操作(前端加密,后端解密)

    用户密码的加密解密操作 作者是个小菜狗,行文过程基本都基于自己理解,没有深入查阅文献,如有错误,还请大神指出 背景: 公司做的是一个某某平台的系统,包括前台和后台,作者刚毕业,刚开始试用,带我的师傅让 ...

  3. Java使用AES/EBC/PKCS5Padding加密,CryptoJS解密错误

    const key = CryptoJS.enc.Utf8.parse('你的秘钥'); // 这里是需要注意的地方// 其次就是{mode: CryptoJS.mode.ECB},我用的是4.1.1 ...

  4. md5加密 java原理_md5 32位 加密原理 Java实现md5加密

    md5 32位 加密原理 简单概括起来,MD5 算法的过程分为四步:处理原文,设置初始值,循环加工,拼接结果. 第一步:处理原文 首先,我们计算出原文长度(bit)对 512 求余的结果,如果不等于 ...

  5. 1、【java数据安全】数据安全之加密解密(base64、MD、SHA、DES、AES、IDEA、PBE、DH、RSA、EIGamal)、数字签名(DSA、ECDSA)和数字证书介绍、应用示例详细介绍

    java数据安全 系列文章 1.[java数据安全]数据安全之加密解密(base64.MD.SHA.DES.AES.IDEA.PBE.DH.RSA.EIGamal).数字签名(DSA.ECDSA)和数 ...

  6. Java使用Hutool工具完成加密解密

    说明 POM 使用Hutool加密解密工具时,引入如下依赖 <dependency><groupId>cn.hutool</groupId><artifact ...

  7. api加密 java_API接口 AES简单加密(Java版本)

    业务场景 APP跟服务端接口通讯有部分数据比较敏感不像被爬虫抓取所以想用对参数进行一些加密 搜了一些资料,目前好像用的比较多的就是 这里主要记录下我使用的 ASE加密方式 1.MD5加密(只能加不能解 ...

  8. java 给pdf解密_PDF文件如何解密?分享一个简单的PDF解密方法

    PDF加密文件如何解密?有些时候为了文件的安全,我们会在PDF文件上加上密码.这里虽然提高了安全性,但是过段时间我们自己需要使用时,同样需要进行解密,不过有些朋友并不知道该如何解密.因此,今天小编就分 ...

  9. js插件jsencrypt实现rsa前端加密php后台解密

    前端页面代码 传递到php后台的是公钥加密的数据 <!DOCTYPE html> <html lang="en"> <head><meta ...

最新文章

  1. [bzoj4562][Haoi2016]食物链_记忆化搜索_动态规划
  2. 批量单变量求解 office wps 单变量求解比较
  3. 在JavaScript中使用json.js:访问JSON编码的某个值
  4. ASP.NET MVC3 系列教程 - 部署你的WEB应用到IIS 6.0
  5. Android CountDownTimer示例
  6. 更好的理解装饰设计模式和代理设计模式
  7. java 避免gc_减少JAVA GC
  8. TDS水质及电导率计算方法及电路程序设计
  9. 2020-11-16学习总结: sass配置
  10. Android系统优化实操总结
  11. html规范eml文件,eml 文件头解析
  12. 笔记本添加固态硬盘记
  13. 5.Numpy数组中数据的抽取
  14. win10 linux 修复引导菜单,win10 + Ubuntu16.04双系统修复linux grub引导丢失
  15. 通信原理眼图画法_四川大学通信原理眼图实验
  16. 20201124 fpga程序的下载
  17. 【NRF51822】百度手环开源源码分析--框架部分
  18. Linux环境问题--Miniconda安装python环境搭建
  19. 2023最新世界大学排名,重磅发布!
  20. java打印空心六边形_带文字的空心六边形。

热门文章

  1. 全国计算机考试比省级的难吗,国考和省考考题的区别,难度差异很大吗?
  2. lpk劫持方式粘滞键后门后门T00ls Lpk Sethc v3.0 正式版下载
  3. ps怎么将png做成gif_用ps将一组图片序列做成GIF
  4. STM32CUBEIDE配置FreeRTOS
  5. oracle正则表达式匹配字母,oracle正则表达式函数 匹配
  6. 富文本编辑器导出html静态页面和pdf格式文件
  7. 用python做一个好玩的数字炸弹游戏
  8. 好玩的猜数游戏(不是二分查找!四位数)
  9. web全栈工程师技能介绍
  10. android音乐播放器实验报告总结,音乐播放器设计实验报告.docx