貼上工具類
package com.common.utils; import javax.crypto.Cipher; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.HashMap; import java.util.Map; /** * RSA 工具類。提供加密,解密,生成密鑰對等方法。 * 需要到 下載bcprov-jdk14-123.jar。 * */ public class RSAUtils { private static final int MAX_ENCRYPT_BLOCK = 117; // RSA最大加密明文大小 private static final int MAX_DECRYPT_BLOCK = 128; // RSA最大解密密文大小 /** * 生成公鑰和私鑰 * * @throws NoSuchAlgorithmException */ public static KeyPair genRSAKeyPair() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); keyPairGen.initialize(1024); return keyPairGen.generateKeyPair(); } /** * 使用模和指數生成RSA公鑰 * 注意:【此代碼用了默認補位方式,為RSA/None/PKCS1Padding,不同JDK默認的補位方式可能不同,如Android默認是RSA * /None/NoPadding】 * * @param modulus 模 * @param exponent 指數 * @return */ public static RSAPublicKey getPublicKey(String modulus, String exponent) { try { BigInteger b1 = new BigInteger(modulus, 16); BigInteger b2 = new BigInteger(exponent, 16); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2); return (RSAPublicKey) keyFactory.generatePublic(keySpec); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 使用模和指數生成RSA私鑰 * 注意:【此代碼用了默認補位方式,為RSA/None/PKCS1Padding,不同JDK默認的補位方式可能不同,如Android默認是RSA * /None/NoPadding】 * * @param modulus 模 * @param exponent 指數 * @return */ public static RSAPrivateKey getPrivateKey(String modulus, String exponent) { try { BigInteger b1 = new BigInteger(modulus, 16); BigInteger b2 = new BigInteger(exponent, 16); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2); return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 公鑰加密 */ public static byte[] encryptByPublicKey(byte[] data, RSAPublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); int inputLen = data.length; try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { int offSet = 0; byte[] cache; int i = 0; // 對數據分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } return out.toByteArray(); } } /** * 私鑰解密 */ public static String decryptByPrivateKey(byte[] encryptedData, RSAPrivateKey privateKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); int inputLen = encryptedData.length; try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { int offSet = 0; byte[] cache; int i = 0; // 對數據分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } return new String(out.toByteArray(), "utf-8"); } } /** * ASCII碼轉BCD碼 */ public static byte[] ASCII_To_BCD(byte[] ascii, int asc_len) { byte[] bcd = new byte[asc_len / 2]; int j = 0; for (int i = 0; i < (asc_len + 1) / 2; i++) { bcd[i] = asc_to_bcd(ascii[j++]); bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i] << 4)); } return bcd; } public static byte asc_to_bcd(byte asc) { byte bcd; if ((asc >= '0') && (asc <= '9')) bcd = (byte) (asc - '0'); else if ((asc >= 'A') && (asc <= 'F')) bcd = (byte) (asc - 'A' + 10); else if ((asc >= 'a') && (asc <= 'f')) bcd = (byte) (asc - 'a' + 10); else bcd = (byte) (asc - 48); return bcd; } /** * BCD轉字符串 */ public static String bcd2Str(byte[] bytes) { char temp[] = new char[bytes.length * 2], val; for (int i = 0; i < bytes.length; i++) { val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f); temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0'); val = (char) (bytes[i] & 0x0f); temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0'); } return new String(temp); } /** * 拆分字符串 */ public static String[] splitString(String string, int len) { int x = string.length() / len; int y = string.length() % len; int z = 0; if (y != 0) { z = 1; } String[] strings = new String[x + z]; String str = ""; for (int i = 0; i < x + z; i++) { if (i == x + z - 1 && y != 0) { str = string.substring(i * len, i * len + y); } else { str = string.substring(i * len, i * len + len); } strings[i] = str; } return strings; } /** * 拆分數組 */ public static byte[][] splitArray(byte[] data, int len) { int x = data.length / len; int y = data.length % len; int z = 0; if (y != 0) { z = 1; } byte[][] arrays = new byte[x + z][]; byte[] arr; for (int i = 0; i < x + z; i++) { arr = new byte[len]; if (i == x + z - 1 && y != 0) { System.arraycopy(data, i * len, arr, 0, y); } else { System.arraycopy(data, i * len, arr, 0, len); } arrays[i] = arr; } return arrays; } //String 解密 public static String Decrypt(String str,String mou,String m) throws Exception{ //模hex String modulus =mou; //私鑰指數hex String private_exponent = m; RSAPrivateKey priKey = getPrivateKey(modulus, private_exponent); return decryptByPrivateKey(HexUtil.hexStringToBytes(str), priKey); } //獲取模塊信息 public static Map getModulus () throws NoSuchAlgorithmException{ KeyPair keyPair = genRSAKeyPair(); Map map = new HashMap(); //生成公鑰和私鑰 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); //模hex String modulus = publicKey.getModulus().toString(16); //公鑰指數hex String public_exponent = publicKey.getPublicExponent().toString(16); //私鑰指數hex String private_exponent = privateKey.getPrivateExponent().toString(16); map.put("g", public_exponent); map.put("m", private_exponent); map.put("modu", modulus); return map; } public static void main(String[] args) throws Exception { KeyPair keyPair = genRSAKeyPair(); //生成公鑰和私鑰 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); //模hex String modulus = publicKey.getModulus().toString(16); //公鑰指數hex String public_exponent = publicKey.getPublicExponent().toString(16); //私鑰指數hex String private_exponent = privateKey.getPrivateExponent().toString(16); System.out.println("public_modulus: " + modulus); System.out.println("public_exponent: " + public_exponent); System.out.println("private_exponent: " + private_exponent); //明文 String plaintStr = "123456"; System.out.println("plaintStr: " + plaintStr); //使用模和指數生成公鑰和私鑰 RSAPublicKey pubKey = getPublicKey(modulus, public_exponent); RSAPrivateKey priKey = getPrivateKey(modulus, private_exponent); //公鑰加密后的密文 byte[] encryptStr = encryptByPublicKey(plaintStr.getBytes("utf-8"), pubKey); System.out.println("encryptStr: " + HexUtil.bytesToHexString(encryptStr)); String jmh = HexUtil.bytesToHexString(encryptStr); System.out.println("start"); //私鑰解密后的明文 System.out.println("decryptStr: " + decryptByPrivateKey(HexUtil.hexStringToBytes(jmh), priKey)); } }
package com.common.utils; public class HexUtil { /** * 二進制byte數組轉十六進制byte數組 * byte array to hex * * @param b byte array * @return hex string */ public static String byte2hex(byte[] b) { StringBuilder hs = new StringBuilder(); String stmp; for (int i = 0; i < b.length; i++) { stmp = Integer.toHexString(b[i] & 0xFF).toUpperCase(); if (stmp.length() == 1) { hs.append("0").append(stmp); } else { hs.append(stmp); } } return hs.toString(); } /** * 十六進制byte數組轉二進制byte數組 * hex to byte array * * @param hex hex string * @return byte array */ public static byte[] hex2byte(String hex) throws IllegalArgumentException{ if (hex.length() % 2 != 0) { throw new IllegalArgumentException ("invalid hex string"); } char[] arr = hex.toCharArray(); byte[] b = new byte[hex.length() / 2]; for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) { String swap = "" + arr[i++] + arr[i]; int byteint = Integer.parseInt(swap, 16) & 0xFF; b[j] = new Integer(byteint).byteValue(); } return b; } public static String bytesToHexString(byte[] src){ StringBuilder stringBuilder = new StringBuilder(""); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } public static byte[] hexStringToBytes(String hexString) { if (hexString == null || hexString.equals("")) { return null; } hexString = hexString.toUpperCase(); int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } }
前端調用
<!-- js必要 -->
<script language="JavaScript" type="text/javascript" src="http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js"></script>
<script language="JavaScript" type="text/javascript" src="http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn2.js"></script>
<script language="JavaScript" type="text/javascript" src="http://www-cs-students.stanford.edu/~tjw/jsbn/prng4.js"></script>
<script language="JavaScript" type="text/javascript" src="http://www-cs-students.stanford.edu/~tjw/jsbn/rng.js"></script>
<script language="JavaScript" type="text/javascript" src="http://www-cs-students.stanford.edu/~tjw/jsbn/rsa.js"></script>
<script language="JavaScript" type="text/javascript" src="http://www-cs-students.stanford.edu/~tjw/jsbn/rsa2.js"></script>
//2獲取加密信息
function getModule() {
var that = this;
$.ajax("${ctx}/wechat/reader/getMoudle.do", {
dataType: 'json', //服務器返回json格式數據
async: false,
type: 'post', //HTTP請求類型
timeout: 10000, //超時時間設置為10秒;
success: function (data) {
that.RSADo.modulus = data.modu;
that.RSADo.publicExponent = data.g;
},
error: function (xhr, type, errorThrown) {
}
});
}
//公鑰加密方法
function encryption(str) {
// 實例化js的RSA對象生成
var rsa = new RSAKey()
rsa.setPublic(this.RSADo.modulus, this.RSADo.publicExponent)
var encryptStr = rsa.encrypt(str);
return encryptStr;
}
//調用
var password = this.encryption(this.password);
后端方法實現及解密調用
//聲明加密秘鑰 private static String m; //聲明加密模塊 private static String mou; //調用RSA工具類的getModulus方法獲取配套的公鑰,秘鑰,和加密模塊信息,並將公鑰和加密模塊傳送到前台,秘鑰和加密模塊 //保存到后台 @ResponseBody @RequestMapping(value = "/getMoudle", method = RequestMethod.POST) public Object getMoudle() throws NoSuchAlgorithmException { Map jmInfo = RSAUtils.getModulus(); String my = jmInfo.get("m").toString(); m = my; mou = jmInfo.get("modu").toString(); return jmInfo; } //解密調用 String password = RSAUtils.Decrypt(password,mou,m);