须要用到一个jar

http://www.bouncycastle.org/latest_releases.html

须要注意的问题

JS用同一秘钥生成的密文用java解密出来是逆序的,即js加密123456用java解密出来是654321,原因未知,须要解密js加密的密文请使用后缀为byJs的方法。

HexUtil.java

> 1];

        // two characters form the hex value.
for (int i = 0, j = 0; j >> 4];
out[j++] = toDigits[0x0F & data[i]];
}
return out;
}
}
" data-snippet-id="ext.95f10f39d6786f444dfe7f63f74db7ec" data-snippet-saved="false" data-csrftoken="ccbrPHwP-WyjtuyjuHUnUI5J2rTNMwFME_ks" data-codota-status="done">package cn.edu.zafu.utils; public class HexUtil {
private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; public static byte[] decodeHex(final char[] data) throws Exception { final int len = data.length; if ((len & 0x01) != 0) {
throw new Exception("Odd number of characters.");
} final byte[] out = new byte[len >> 1]; // two characters form the hex value.
for (int i = 0, j = 0; j < len; i++) {
int f = toDigit(data[j], j) << 4;
j++;
f = f | toDigit(data[j], j);
j++;
out[i] = (byte) (f & 0xFF);
} return out;
} protected static int toDigit(final char ch, final int index)
throws Exception {
final int digit = Character.digit(ch, 16);
if (digit == -1) {
throw new Exception("Illegal hexadecimal character " + ch
+ " at index " + index);
}
return digit;
} public static char[] encodeHex(final byte[] data) {
return encodeHex(data, true);
} public static char[] encodeHex(final byte[] data, final boolean toLowerCase) {
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
} protected static char[] encodeHex(final byte[] data, final char[] toDigits) {
final int l = data.length;
final char[] out = new char[l << 1];
// two characters form the hex value.
for (int i = 0, j = 0; i < l; i++) {
out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
out[j++] = toDigits[0x0F & data[i]];
}
return out;
}
}

StringUtil.java

package cn.edu.zafu.utils;

public class StringUtil {

    public static boolean isBlank(final CharSequence cs) {
int strLen;
if (cs == null || (strLen = cs.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if (Character.isWhitespace(cs.charAt(i)) == false) {
return false;
}
}
return true;
} public static String reverse(final String str) {
if (str == null) {
return null;
}
return new StringBuilder(str).reverse().toString();
}
}

FileUtil.java

package cn.edu.zafu.utils;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream; public class FileUtils { public static FileInputStream openInputStream(File file) throws IOException {
if (file.exists()) {
if (file.isDirectory()) {
throw new IOException("File '" + file
+ "' exists but is a directory");
}
if (file.canRead() == false) {
throw new IOException("File '" + file + "' cannot be read");
}
} else {
throw new FileNotFoundException("File '" + file
+ "' does not exist");
}
return new FileInputStream(file);
} public static FileOutputStream openOutputStream(File file)
throws IOException {
return openOutputStream(file, false);
} public static FileOutputStream openOutputStream(File file, boolean append)
throws IOException {
if (file.exists()) {
if (file.isDirectory()) {
throw new IOException("File '" + file
+ "' exists but is a directory");
}
if (file.canWrite() == false) {
throw new IOException("File '" + file
+ "' cannot be written to");
}
} else {
File parent = file.getParentFile();
if (parent != null) {
if (!parent.mkdirs() && !parent.isDirectory()) {
throw new IOException("Directory '" + parent
+ "' could not be created");
}
}
}
return new FileOutputStream(file, append);
} public static void closeQuietly(InputStream input) {
closeQuietly((Closeable) input);
} public static void closeQuietly(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (IOException ioe) {
// ignore
}
}
}

RSAUtil.java

package cn.edu.zafu.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.Provider;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidParameterException;
import java.security.interfaces.RSAPublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.RSAPublicKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.InvalidKeySpecException; import javax.crypto.Cipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; /**
* RSA算法加密/解密工具类。
*
*
*/
public abstract class RSAUtil { /** 算法名称 */
private static final String ALGORITHOM = "RSA";
/**保存生成的密钥对的文件名。 */
private static final String RSA_PAIR_FILENAME = "/__RSA_PAIR.txt";
/** 密钥大小 */
private static final int KEY_SIZE = 1024;
/** 默认的安全服务提供者 */
private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider(); private static KeyPairGenerator keyPairGen = null;
private static KeyFactory keyFactory = null;
/** 缓存的密钥对。 */
private static KeyPair oneKeyPair = null; private static File rsaPairFile = null; static {
try {
keyPairGen = KeyPairGenerator.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
keyFactory = KeyFactory.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
} catch (NoSuchAlgorithmException ex) {
System.out.println(ex.getMessage());
}
rsaPairFile = new File(getRSAPairFilePath());
} private RSAUtil() {
} /**
* 生成并返回RSA密钥对。 */
private static synchronized KeyPair generateKeyPair() {
try {
keyPairGen.initialize(KEY_SIZE, new SecureRandom(new SimpleDateFormat("yyyyMMdd").format(new Date()).getBytes()));
oneKeyPair = keyPairGen.generateKeyPair();
saveKeyPair(oneKeyPair);
return oneKeyPair;
} catch (InvalidParameterException ex) {
System.out.println("KeyPairGenerator does not support a key length of " + KEY_SIZE + ".");
ex.printStackTrace();
} catch (NullPointerException ex) {
System.out.println("RSAUtils#KEY_PAIR_GEN is null, can not generate KeyPairGenerator instance.");
ex.printStackTrace();
}
return null;
} /**
* 返回生成/读取的密钥对文件的路径。
*/
private static String getRSAPairFilePath() {
String urlPath = RSAUtil.class.getResource("/").getPath();
return (new File(urlPath).getParent() + RSA_PAIR_FILENAME);
} /**
* 若须要创建新的密钥对文件,则返回 {@code true}。否则 {@code false}。 */
private static boolean isCreateKeyPairFile() {
// 是否创建新的密钥对文件
boolean createNewKeyPair = false;
if (!rsaPairFile.exists() || rsaPairFile.isDirectory()) {
createNewKeyPair = true;
}
return createNewKeyPair;
} /**
* 将指定的RSA密钥对以文件形式保存。
*
* @param keyPair 要保存的密钥对。 */
private static void saveKeyPair(KeyPair keyPair) {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = FileUtils.openOutputStream(rsaPairFile);
oos = new ObjectOutputStream(fos);
oos.writeObject(keyPair);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
FileUtils.closeQuietly(oos);
FileUtils.closeQuietly(fos);
}
} /**
* 返回RSA密钥对。 */
public static KeyPair getKeyPair() {
// 首先推断是否须要又一次生成新的密钥对文件
if (isCreateKeyPairFile()) {
// 直接强制生成密钥对文件,并存入缓存。
return generateKeyPair();
}
if (oneKeyPair != null) {
return oneKeyPair;
}
return readKeyPair();
} // 同步读出保存的密钥对
private static KeyPair readKeyPair() {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = FileUtils.openInputStream(rsaPairFile);
ois = new ObjectInputStream(fis);
oneKeyPair = (KeyPair) ois.readObject();
return oneKeyPair;
} catch (Exception ex) {
ex.printStackTrace();
} finally {
FileUtils.closeQuietly(ois);
FileUtils.closeQuietly(fis);
}
return null;
} /**
* 依据给定的系数和专用指数构造一个RSA专用的公钥对象。 *
* @param modulus 系数。
* @param publicExponent 专用指数。 * @return RSA专用公钥对象。 */
public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) {
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(new BigInteger(modulus),
new BigInteger(publicExponent));
try {
return (RSAPublicKey) keyFactory.generatePublic(publicKeySpec);
} catch (InvalidKeySpecException ex) {
System.out.println("RSAPublicKeySpec is unavailable.");
ex.printStackTrace();
} catch (NullPointerException ex) {
System.out.println("RSAUtils#KEY_FACTORY is null, can not generate KeyFactory instance.");
ex.printStackTrace();
}
return null;
} /**
* 依据给定的系数和专用指数构造一个RSA专用的私钥对象。
*
* @param modulus 系数。
* @param privateExponent 专用指数。
* @return RSA专用私钥对象。
*/
public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) {
RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus),
new BigInteger(privateExponent));
try {
return (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);
} catch (InvalidKeySpecException ex) {
System.out.println("RSAPrivateKeySpec is unavailable.");
ex.printStackTrace();
} catch (NullPointerException ex) {
System.out.println("RSAUtils#KEY_FACTORY is null, can not generate KeyFactory instance.");
ex.printStackTrace();
}
return null;
} /**
* 依据给定的16进制系数和专用指数字符串构造一个RSA专用的私钥对象。
*
* @param modulus 系数。
* @param privateExponent 专用指数。 * @return RSA专用私钥对象。 */
public static RSAPrivateKey getRSAPrivateKey(String hexModulus, String hexPrivateExponent) {
if(StringUtil.isBlank(hexModulus) || StringUtil.isBlank(hexPrivateExponent)) {
System.out.println("hexModulus and hexPrivateExponent cannot be empty. RSAPrivateKey value is null to return.");
return null;
}
byte[] modulus = null;
byte[] privateExponent = null;
try {
modulus = HexUtil.decodeHex(hexModulus.toCharArray());
privateExponent = HexUtil.decodeHex(hexPrivateExponent.toCharArray());
} catch(Exception ex) {
System.out.println("hexModulus or hexPrivateExponent value is invalid. return null(RSAPrivateKey).");
ex.printStackTrace();
}
if(modulus != null && privateExponent != null) {
return generateRSAPrivateKey(modulus, privateExponent);
}
return null;
}
/**
* 依据给定的16进制系数和专用指数字符串构造一个RSA专用的公钥对象。 *
* @param modulus 系数。 * @param publicExponent 专用指数。 * @return RSA专用公钥对象。
*/
public static RSAPublicKey getRSAPublicKey(String hexModulus, String hexPublicExponent) {
if(StringUtil.isBlank(hexModulus) || StringUtil.isBlank(hexPublicExponent)) {
System.out.println("hexModulus and hexPublicExponent cannot be empty. return null(RSAPublicKey).");
return null;
}
byte[] modulus = null;
byte[] publicExponent = null;
try {
modulus = HexUtil.decodeHex(hexModulus.toCharArray());
publicExponent = HexUtil.decodeHex(hexPublicExponent.toCharArray());
} catch(Exception ex) {
System.out.println("hexModulus or hexPublicExponent value is invalid. return null(RSAPublicKey).");
ex.printStackTrace();
}
if(modulus != null && publicExponent != null) {
return generateRSAPublicKey(modulus, publicExponent);
}
return null;
}
/**
* 使用指定的公钥加密数据。
*
* @param publicKey 给定的公钥。
* @param data 要加密的数据。
* @return 加密后的数据。 */
public static byte[] encrypt(PublicKey publicKey, byte[] data) throws Exception {
Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
ci.init(Cipher.ENCRYPT_MODE, publicKey);
return ci.doFinal(data);
} /**
* 使用指定的私钥解密数据。
*
* @param privateKey 给定的私钥。
* @param data 要解密的数据。
* @return 原数据。
*/
public static byte[] decrypt(PrivateKey privateKey, byte[] data) throws Exception {
Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
ci.init(Cipher.DECRYPT_MODE, privateKey);
return ci.doFinal(data);
} /**
* 使用给定的公钥加密给定的字符串。 * <p />
* 若 {@code publicKey} 为 {@code null}。或者 {@code plaintext} 为 {@code null} 则返回 {@code
* null}。
*
* @param publicKey 给定的公钥。
* @param plaintext 字符串。
* @return 给定字符串的密文。
*/
public static String encryptString(PublicKey publicKey, String plaintext) {
if (publicKey == null || plaintext == null) {
return null;
}
byte[] data = plaintext.getBytes();
try {
byte[] en_data = encrypt(publicKey, data);
return new String(HexUtil.encodeHex(en_data));
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
} /**
* 使用默认的公钥加密给定的字符串。
* <p />
* 若{@code plaintext} 为 {@code null} 则返回 {@code null}。
*
* @param plaintext 字符串。
* @return 给定字符串的密文。
*/
public static String encryptString(String plaintext) {
if(plaintext == null) {
return null;
}
byte[] data = plaintext.getBytes();
KeyPair keyPair = getKeyPair();
try {
byte[] en_data = encrypt((RSAPublicKey)keyPair.getPublic(), data);
return new String(HexUtil.encodeHex(en_data));
} catch(NullPointerException ex) {
System.out.println("keyPair cannot be null.");
ex.printStackTrace();
} catch(Exception ex) {
ex.printStackTrace();
}
return null;
} /**
* 生成由JS的RSA加密的字符串。 * @param publicKey 公钥
* @param plaintext 原文字符串
* @return 加密后的字符串
*/
public static String encryptStringByJs(PublicKey publicKey, String plaintext) {
if(plaintext == null) {
return null;
}
String text = encryptString(publicKey,StringUtil.reverse(plaintext)); return text;
}
/**
* 用默认公钥生成由JS的RSA加密的字符串。
* @param publicKey 公钥
* @param plaintext 原文字符串
* @return 加密后的字符串
*/
public static String encryptStringByJs( String plaintext) {
if(plaintext == null) {
return null;
}
String text = encryptString(StringUtil.reverse(plaintext)); return text;
}
/**
* 使用给定的私钥解密给定的字符串。 * <p />
* 若私钥为 {@code null},或者 {@code encrypttext} 为 {@code null}或空字符串则返回 {@code null}。
* 私钥不匹配时,返回 {@code null}。
*
* @param privateKey 给定的私钥。 * @param encrypttext 密文。 * @return 原文字符串。 */
public static String decryptString(PrivateKey privateKey, String encrypttext) {
if (privateKey == null || StringUtil.isBlank(encrypttext)) {
return null;
}
try {
byte[] en_data =HexUtil.decodeHex(encrypttext.toCharArray());
byte[] data = decrypt(privateKey, en_data);
return new String(data);
} catch (Exception ex) {
System.out.println(String.format("\"%s\" Decryption failed. Cause: %s", encrypttext, ex.getCause().getMessage())); }
return null;
} /**
* 使用默认的私钥解密给定的字符串。
* <p />
* 若{@code encrypttext} 为 {@code null}或空字符串则返回 {@code null}。
* 私钥不匹配时,返回 {@code null}。
*
* @param encrypttext 密文。
* @return 原文字符串。
*/
public static String decryptString(String encrypttext) {
if(StringUtil.isBlank(encrypttext)) {
return null;
}
KeyPair keyPair = getKeyPair();
try {
byte[] en_data = HexUtil.decodeHex(encrypttext.toCharArray());
byte[] data = decrypt((RSAPrivateKey)keyPair.getPrivate(), en_data);
return new String(data);
} catch(NullPointerException ex) {
System.out.println("keyPair cannot be null.");
ex.printStackTrace();
} catch (Exception ex) {
System.out.println(String.format("\"%s\" Decryption failed. Cause: %s", encrypttext, ex.getMessage()));
ex.printStackTrace();
}
return null;
} /**
* 使用指定的私钥解密由JS加密的字符串。
* @param privateKey 私钥
* @param encrypttext 密文
* @return {@code encrypttext} 的原文字符串
*/
public static String decryptStringByJs(PrivateKey privateKey,String encrypttext) {
String text = decryptString(privateKey,encrypttext);
if(text == null) {
return null;
}
return StringUtil.reverse(text);
}
/**
* 使用默认的私钥解密由JS加密(使用此类提供的公钥加密)的字符串。
*
* @param encrypttext 密文。 * @return {@code encrypttext} 的原文字符串。
*/
public static String decryptStringByJs(String encrypttext) {
String text = decryptString(encrypttext);
if(text == null) {
return null;
}
return StringUtil.reverse(text);
} /** 返回已初始化的默认的公钥。 */
public static RSAPublicKey getDefaultPublicKey() {
KeyPair keyPair = getKeyPair();
if(keyPair != null) {
return (RSAPublicKey)keyPair.getPublic();
}
return null;
} /** 返回已初始化的默认的私钥。*/
public static RSAPrivateKey getDefaultPrivateKey() {
KeyPair keyPair = getKeyPair();
if(keyPair != null) {
return (RSAPrivateKey)keyPair.getPrivate();
}
return null;
} }

源代码下载

http://download.csdn.net/detail/sbsujjbcy/8897029

JAVA的RSA加密算法工具类的更多相关文章

  1. Rhino+envjs-1.2.js 在java运行网站js 工具类

    java爬虫遇到个页面加密的东西,找了些资料学习学习 做了个java运行js的工具类,希望对大家有用,其中用到client(获取js)可以自行换成自己的client.主要是用了 Rhino就是Java ...

  2. java中常用的工具类(一)

    我们java程序员在开发项目的是常常会用到一些工具类.今天我汇总了一下java中常用的工具方法.大家可以在项目中使用.可以收藏!加入IT江湖官方群:383126909 我们一起成长 一.String工 ...

  3. Java学习-041-颜色工具类(RGB,HEX)

    在日常的网页开发中,经常需要进行颜色数值获取.转换,例如获取红色,获取蓝色,获取绿色,RGB转十六进制颜色,十六进制颜色转RGB等,因而在学习过程中,写了一个小工具类,仅供各位小主参考! 多不闲言,直 ...

  4. JAVA中封装JSONUtils工具类及使用

    在JAVA中用json-lib-2.3-jdk15.jar包中提供了JSONObject和JSONArray基类,用于JSON的序列化和反序列化的操作.但是我们更习惯将其进一步封装,达到更好的重用. ...

  5. JAVA自动生成正则表达式工具类

    经过很久的努力,终于完成了JAVA自动生成正则表达式工具类.还记得之前需要正则,老是从网上找吗?找了想修改也不会修改.现在不用再为此烦恼了,使用此生成类轻松搞定所有正则表达式.赶快在同事面前炫一下吧. ...

  6. java 二进制数字符串转换工具类

    java 二进制数字符串转换工具类 将二进制转换成八进制 将二进制转换成十进制 将二进制转换成十六进制 将十进制转换成二进制 package com.iteye.injavawetrust.ad; i ...

  7. Java学习-049-正则工具类

    自去年九月份决定再次入学和职业资格进阶,开始备战二者考试至今,以及当下进行中的职称申请,犹如孤独的狼,不断前行在路上,而今凡凡总总的已历8月... 不感慨了,如下为一园友需要的正则工具类,直接上码: ...

  8. Java 后台验证的工具类

    Java 后台验证的工具类 public class ValidationUtil {         //手机号     public static String mobile = "^( ...

  9. java后端时间处理工具类,返回 "XXX 前" 的字符串

    转自:https://www.cnblogs.com/devise/p/9974672.html 我们经常会遇到显示 "某个之间之前" 的需求(比如各种社交软件,在回复消息时,显示 ...

随机推荐

  1. javascript获取CSS3浏览器前缀

    var prefix = (function () { var styles = window.getComputedStyle(document.documentElement, ''), pre ...

  2. Linux中 pid_t 类型的定义.

    说明:涉及到的头文件(.h),目录默认都是基于 /usr/include/ 目录. 1.在 "/sys/types.h"中,有下列内容: #include <bits/typ ...

  3. csms发布步骤

    1.wcf发布 通过点击 CSMS2.Application,右键发布按钮,将文件拷贝 2.打包文件 CSMS2.Resources 中 update.config 修改为对应 ServerUrl地址 ...

  4. Swift和OC混编时, 关于@objc的作用

    Objective-C 和 Swift 在底层使用的是两套完全不同的机制,Cocoa 中的 Objective-C 对象是基于运行时的,它从骨子里遵循了 KVC (Key-Value Coding,通 ...

  5. 使用CAEmitterLayer产生粒子效果

    ViewController.m #import "ViewController.h" @implementation ViewController - (void)viewDid ...

  6. javascript 广告移动特效

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  7. 六种方式实现hibernate查询

    最近在学习Hibernate的基本内容,刚好在项目中有用到,基本上都是用到哪就学哪. 今天看看六种方式实现hibernate查询......... 分别是HQL查询,对象化查询Criteria方法,动 ...

  8. Oracle Union All 排序

    在oracle中使用union all或者 union 对两个结果集进行并集操作时,如果需要对查询结果集进行排序时,不能直接在后面加order by + 表字段 来排序 例如: 在oracle的soc ...

  9. xml配置与使用

    php100:89:xml常识知识补充 xml常识知识补充XML(即可扩展标记语言,它与HTML一样,都是标准通用标记语言.Xml是Internet环境中跨平台的,依赖于内容的技术.扩展标记语言XML ...

  10. The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. (关于jdbc)

    The last packet sent successfully to the server was milliseconds ago. The driver has not received an ...