java前后端密码加密
贴上工具类
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);
版权声明:本文为yyKong原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。