JAVA 中解密RSA算法JS加密实例详解

JAVA 中解密RSA算法JS加密实例详解

有这样一个需求,前端登录的用户名密码,密码必需加密,但不可使用MD5,因为后台要检测密码的复杂度,那么在保证安全的前提下将密码传到后台呢,答案就是使用RSA非对称加密算法解决 。

java代码

需要依赖 commons-codec 包

RSACoder.Java

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by lake on 17-4-12.
 */
public class RSACoder {
  public static final String KEY_ALGORITHM = "RSA";
  public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

  private static final String PUBLIC_KEY = "RSAPublicKey";
  private static final String PRIVATE_KEY = "RSAPrivateKey";

  public static byte[] decryptBASE64(String key) {
    return Base64.decodeBase64(key);
  }

  public static String encryptBASE64(byte[] bytes) {
    return Base64.encodeBase64String(bytes);
  }

  /**
   * 用私钥对信息生成数字签名
   *
   * @param data    加密数据
   * @param privateKey 私钥
   * @return
   * @throws Exception
   */
  public static String sign(byte[] data, String privateKey) throws Exception {
    // 解密由base64编码的私钥
    byte[] keyBytes = decryptBASE64(privateKey);
    // 构造PKCS8EncodedKeySpec对象
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    // KEY_ALGORITHM 指定的加密算法
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    // 取私钥匙对象
    PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
    // 用私钥对信息生成数字签名
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initSign(priKey);
    signature.update(data);
    return encryptBASE64(signature.sign());
  }

  /**
   * 校验数字签名
   *
   * @param data   加密数据
   * @param publicKey 公钥
   * @param sign   数字签名
   * @return 校验成功返回true 失败返回false
   * @throws Exception
   */
  public static boolean verify(byte[] data, String publicKey, String sign)
      throws Exception {
    // 解密由base64编码的公钥
    byte[] keyBytes = decryptBASE64(publicKey);
    // 构造X509EncodedKeySpec对象
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    // KEY_ALGORITHM 指定的加密算法
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    // 取公钥匙对象
    PublicKey pubKey = keyFactory.generatePublic(keySpec);
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initVerify(pubKey);
    signature.update(data);
    // 验证签名是否正常
    return signature.verify(decryptBASE64(sign));
  }

  public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception{
    // 对密钥解密
    byte[] keyBytes = decryptBASE64(key);
    // 取得私钥
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    // 对数据解密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    return cipher.doFinal(data);
  }

  /**
   * 解密<br>
   * 用私钥解密
   *
   * @param data
   * @param key
   * @return
   * @throws Exception
   */
  public static byte[] decryptByPrivateKey(String data, String key)
      throws Exception {
    return decryptByPrivateKey(decryptBASE64(data),key);
  }

  /**
   * 解密<br>
   * 用公钥解密
   *
   * @param data
   * @param key
   * @return
   * @throws Exception
   */
  public static byte[] decryptByPublicKey(byte[] data, String key)
      throws Exception {
    // 对密钥解密
    byte[] keyBytes = decryptBASE64(key);
    // 取得公钥
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key publicKey = keyFactory.generatePublic(x509KeySpec);
    // 对数据解密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, publicKey);
    return cipher.doFinal(data);
  }

  /**
   * 加密<br>
   * 用公钥加密
   *
   * @param data
   * @param key
   * @return
   * @throws Exception
   */
  public static byte[] encryptByPublicKey(String data, String key)
      throws Exception {
    // 对公钥解密
    byte[] keyBytes = decryptBASE64(key);
    // 取得公钥
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key publicKey = keyFactory.generatePublic(x509KeySpec);
    // 对数据加密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    return cipher.doFinal(data.getBytes());
  }

  /**
   * 加密<br>
   * 用私钥加密
   *
   * @param data
   * @param key
   * @return
   * @throws Exception
   */
  public static byte[] encryptByPrivateKey(byte[] data, String key)
      throws Exception {
    // 对密钥解密
    byte[] keyBytes = decryptBASE64(key);
    // 取得私钥
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    // 对数据加密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    return cipher.doFinal(data);
  }

  /**
   * 取得私钥
   *
   * @param keyMap
   * @return
   * @throws Exception
   */
  public static String getPrivateKey(Map<String, Key> keyMap)
      throws Exception {
    Key key = (Key) keyMap.get(PRIVATE_KEY);
    return encryptBASE64(key.getEncoded());
  }

  /**
   * 取得公钥
   *
   * @param keyMap
   * @return
   * @throws Exception
   */
  public static String getPublicKey(Map<String, Key> keyMap)
      throws Exception {
    Key key = keyMap.get(PUBLIC_KEY);
    return encryptBASE64(key.getEncoded());
  }

  /**
   * 初始化密钥
   *
   * @return
   * @throws Exception
   */
  public static Map<String, Key> initKey() throws Exception {
    KeyPairGenerator keyPairGen = KeyPairGenerator
        .getInstance(KEY_ALGORITHM);
    keyPairGen.initialize(1024);
    KeyPair keyPair = keyPairGen.generateKeyPair();
    Map<String, Key> keyMap = new HashMap(2);
    keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥
    keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥
    return keyMap;
  }
}

测试类

RSACoderTest.java

import org.junit.Before;
import org.junit.Test;

import java.security.Key;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * Created by lake on 17-4-12.
 */
public class RSACoderTest {
  private String publicKey;
  private String privateKey;

  @Before
  public void setUp() throws Exception {
    Map<String, Key> keyMap = RSACoder.initKey();
    publicKey = RSACoder.getPublicKey(keyMap);
    privateKey = RSACoder.getPrivateKey(keyMap);
    System.err.println("公钥: \n\r" + publicKey);
    System.err.println("私钥: \n\r" + privateKey);
  }

  @Test
  public void test() throws Exception {
    System.err.println("公钥加密——私钥解密");
    String inputStr = "abc";
    byte[] encodedData = RSACoder.encryptByPublicKey(inputStr, publicKey);
    byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,
        privateKey);
    String outputStr = new String(decodedData);
    System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
    assertEquals(inputStr, outputStr);
  }

  @Test
  public void testSign() throws Exception {
    System.err.println("私钥加密——公钥解密");
    String inputStr = "sign";
    byte[] data = inputStr.getBytes();
    byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);
    byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);
    String outputStr = new String(decodedData);
    System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
    assertEquals(inputStr, outputStr);
    System.err.println("私钥签名——公钥验证签名");
    // 产生签名
    String sign = RSACoder.sign(encodedData, privateKey);
    System.err.println("签名:" + sign);
    // 验证签名
    boolean status = RSACoder.verify(encodedData, publicKey, sign);
    System.err.println("状态:" + status);
    assertTrue(status);
  }
}

前端代码

依赖 jsencrypt 项目

<script src="bin/jsencrypt.min.js"></script>
<script type="text/javascript">
  var encrypt = new JSEncrypt();
  encrypt.setPublicKey('java生成的公钥');
  var encrypted = encrypt.encrypt('加密的字符串');
</script>

说明

前端生成加密的字符串encrypted,传到后台,java使用私钥进行解密即可。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2017-04-13

java 加密之RSA算法加密与解密的实例详解

java 加密之RSA算法加解密与解密的实例详解 前言: RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名.RSA以它的三个发明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名,这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法. RSA的安全基于大数分解的难度.其公钥和私钥是一对大素数(100到200位十进制数或更大)的函

java常用工具类之DES和Base64加密解密类

一.DES加密和解密 package com.itjh.javaUtil; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecExc

java加密算法分享(rsa解密、对称加密、md5加密)

复制代码 代码如下: import java.io.UnsupportedEncodingException;import java.security.InvalidKeyException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import jav

RSA加密算法java简单实现方法(必看)

简单完整的代码,通过这个代码你将对RSA加密算法在Java中的实现方法有一个初步的了解,这个类,你可以直接使用,水平高的,就自己修改完善下代码. package security; import java.security.*; import java.security.spec.*; import java.security.interfaces.*; import javax.crypto.spec.*; import javax.crypto.interfaces.*; import ja

java实现的RSA加密算法详解

本文实例讲述了java实现的RSA加密算法.分享给大家供大家参考,具体如下: 一.什么是非对称加密 1.加密的密钥与加密的密钥不相同,这样的加密算法称之为非对称加密 2.密钥分为:公钥,私钥 公钥:可以对外给任何人的加密和解密的密码,是公开的 私钥:通过私钥可以生成公钥,但从公钥被认为无法生成公钥(被推导出的概率小到不考虑) 3.当将要加密的内容用公钥加密的时候,只能用私钥来解密 当将要加密的内容用私钥加密的时候,只能用公钥来解密 4.公钥与私钥的关系,利用一个简单的公式来生成公钥和私钥,即非对

Java中RSA加密解密的实现方法分析

本文实例讲述了Java中RSA加密解密的实现方法.分享给大家供大家参考,具体如下: public static void main(String[] args) throws Exception { // TODO Auto-generated method stub HashMap<String, Object> map = RSAUtils.getKeys(); //生成公钥和私钥 RSAPublicKey publicKey = (RSAPublicKey) map.get("

Java RSA加密解密实现方法分析【附BASE64 jar包下载】

本文实例讲述了Java RSA加密解密实现方法.分享给大家供大家参考,具体如下: 该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar javabase64-1.3.1.jar 本站下载地址. 注意: RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块进行. RSA加密对明文的长度是有限制的,如果加密数据过大会抛出如下异常: Exception in thread "main" javax.cryp

java使用des加密解密示例分享

复制代码 代码如下: import java.security.Key;import java.security.SecureRandom;import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import javax.crypto.spec.IvPar

JAVA加密算法- 非对称加密算法(DH,RSA)的详细介绍

非对称密码概念 1.与对称加密算法的主要差别在于,加密和解密的密钥不相同,一个公开(公钥),一个保密(私钥).主要解决了对称加密算法密钥分配管理的问题,提高了算法安全性. 2.非对称加密算法的加密.解密的效率比较低.在算法设计上,非对称加密算法对待加密的数据长度有着苛刻的要求.例如RSA算法要求待加密的数据不得大于53个字节. 3.非对称加密算法主要用于 交换对称加密算法的密钥,而非数据交换 4.java6提供实现了DH和RSA两种算法.Bouncy Castle提供了E1Gamal算法支持.除

java 中RSA的方式实现非对称加密的实例

java 中RSA的方式实现非对称加密的实例 RSA通俗理解: 你只要去想:既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密:同理,既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证. 实现代码: package com.sahadev; import java.security.KeyFactory; import java.security.KeyPair; import java.se

java 中DH的方式实现非对称加密的实例

java 中DH的方式实现非对称加密的实例 实现代码: package com.sahadev; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.X509Enco

详解java中通过post方式访问后台服务器

最近在学习java中通过post方式访问后台服务器,那么今天也算个学习笔记吧! 首先,上代码: Runnable payRunnable = new Runnable() { @Override public void run() { try { HashMap<String, String> payParamMap = new HashMap<String, String>(); payParamMap.put("canshu" ,"woshican

Java中map遍历方式的选择问题详解

1. 阐述 对于Java中Map的遍历方式,很多文章都推荐使用entrySet,认为其比keySet的效率高很多.理由是:entrySet方法一次拿到所有key和value的集合:而keySet拿到的只是key的集合,针对每个key,都要去Map中额外查找一次value,从而降低了总体效率.那么实际情况如何呢? 为了解遍历性能的真实差距,包括在遍历key+value.遍历key.遍历value等不同场景下的差异,我试着进行了一些对比测试. 2. 对比测试 一开始只进行了简单的测试,但结果却表明k

Java中5种方式实现String反转

这里介绍Java中5中实现String反转的方式. 一.数组实现String反转 //数组实现String反转 public String reverseByArray(){ if(str == null || str.length() == 1){ return null; } char[] ch = str.toCharArray();//字符串转换成字符数组 for(int i = 0 ; i < ch.length/2 ; i++){ char temp = ch[i]; ch[i] =

java中double转化为BigDecimal精度缺失的实例

java中double转化为BigDecimal精度缺失实例 @SuppressWarnings("static-access") public static void main(String[] args) { System.out.println(3215.10/2); BigDecimal bd = new BigDecimal(3215.10/2); System.out.println(bd); System.out.println(bd.setScale(2, bd.ROU

Java中静态类型检查是如何进行的实例思路详解

以下内容来自维基百科,关于静态类型检查和动态类型检查的解释: •静态类型检查:基于程序的源代码来验证类型安全的过程: •动态类型检查:在程序运行期间验证类型安全的过程: Java使用静态类型检查在编译期间分析程序,确保没有类型错误.基本的思想是不要让类型错误在运行期间发生. 以下代码是一个例子,理解了他,你会更好的理解Java静态类型检查是如何工作的. 代码示例 假定我们有如下类,A和B,B继承A. class A { A me() { return this; } public void do

Java 中桥接模式——对象结构型模式的实例详解

Java  中桥接模式--对象结构型模式的实例详解 一.意图 将抽象部分与它的实现部分分离,使他们都可以独立的变化. 二.适用性 以下一些情况使用Bridge模式 你不希望在抽象和它的实现部分之间有一个固定的绑定关系.例如这种情况可能因为,在程序运行时刻实现部分应可以被选择或者切换. 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充.这时Bridge模式使你可以对不同的抽象接口和实现部分进行组合,并分别对他们进行扩充. 对一个抽象的实现部分的修改应对客户不产生影响,即客户代码不必重新编译

浅谈Java中复制数组的方式

在Java里面,可以用复制语句"A=B"给基本类型的数据传递值,但是如果A,B是两个同类型的数组,复制就相当于将一个数组变量的引用传递给另一个数组:如果一个数组发生改变,那么引用同一数组的变量也要发生改变.         以下是归纳的 java 中复制数组的方法:         (1) 使用FOR循环,将数组的每个元素复制或者复制指定元素,不过效率差一点         (2) 使用clone方法,得到数组的值,而不是引用,不能复制指定元素,灵活性差一点         (3) 使