欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-02-29 16:39:04
java 中解密rsa算法js加密实例详解 有这样一个需求,前端登录的用户名密码,密码必需加密,但不可使用md5,因为后台要检测密码的复杂度,那么在保证安全的前提下将密码...

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使用私钥进行解密即可。

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