后端工具类
package com.xx.auth.utils.encrypt; /** * @Author:zhao-baolin * @Description: * @Date:Created in 2018/7/4 * @Modified By: */ 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' }; /** * 16进制转byte数组 * @param data 16进制字符串 * @return byte数组 * @throws Exception 转化失败的异常 */ public static byte[] hex2Bytes(final String 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.charAt(j), j) << 4; j++; f = f | toDigit(data.charAt(j), j); j++; out[i] = (byte) (f & 0xFF); } return out; } /** * bytes数组转16进制String * @param data bytes数组 * @return 转化结果 */ public static String bytes2Hex(final byte[] data) { return bytes2Hex(data, true); } /** * bytes数组转16进制String * @param data bytes数组 * @param toLowerCase 是否小写 * @return 转化结果 */ public static String bytes2Hex(final byte[] data, final boolean toLowerCase) { return bytes2Hex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); } /** * bytes数组转16进制String * @param data bytes数组 * @param toDigits DIGITS_LOWER或DIGITS_UPPER * @return 转化结果 */ private static String bytes2Hex(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 new String(out); } /** * 16转化为数字 * @param ch 16进制 * @param index 索引 * @return 转化结果 * @throws Exception 转化失败异常 */ private 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; } /* * 16进制字符串转字符串 */ public static String hex2String(String hex) throws Exception{ String r = bytes2String(hexString2Bytes(hex)); return r; } /* * 字节数组转字符串 */ public static String bytes2String(byte[] b) throws Exception { String r = new String (b,"UTF-8"); return r; } /* * 16进制字符串转字节数组 */ public static byte[] hexString2Bytes(String hex) { if ((hex == null) || (hex.equals(""))){ return null; } else if (hex.length()%2 != 0){ return null; } else{ hex = hex.toUpperCase(); int len = hex.length()/2; byte[] b = new byte[len]; char[] hc = hex.toCharArray(); for (int i=0; i<len; i++){ int p=2*i; b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p+1])); } return b; } } /* * 字符转换为字节 */ private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } /* * 字符串转16进制字符串 */ public static String string2HexString(String s) throws Exception{ String r = bytes2HexString(string2Bytes(s)); return r; } /* * 字节数组转16进制字符串 */ public static String bytes2HexString(byte[] b) { String r = ""; for (int i = 0; i < b.length; i++) { String hex = Integer.toHexString(b[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } r += hex.toUpperCase(); } return r; } /* * 字符串转字节数组 */ public static byte[] string2Bytes(String s){ byte[] r = s.getBytes(); return r; } } package com.xx.auth.utils.encrypt; import sun.misc.BASE64Encoder; import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.HashMap; import java.util.Map; /** * @Author:zhao-baolin * @Description: 生成公钥私钥 * @Date:Created in 2018/7/4 * @Modified By: */ public class RSACoder { public static final String KEY_ALGORITHM = "RSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; public class Keys { } //获得公钥 public static String getPublicKey(Map<String, Object> keyMap) throws Exception { //获得map中的公钥对象 转为key对象 Key key = (Key) keyMap.get(PUBLIC_KEY); //byte[] publicKey = key.getEncoded(); //编码返回字符串 return encryptBASE64(key.getEncoded()); } //获得私钥 public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { //获得map中的私钥对象 转为key对象 Key key = (Key) keyMap.get(PRIVATE_KEY); //byte[] privateKey = key.getEncoded(); //编码返回字符串 return encryptBASE64(key.getEncoded()); } //编码返回字符串 public static String encryptBASE64(byte[] key) throws Exception { return (new BASE64Encoder()).encodeBuffer(key); } //map对象中存放公私钥 public static Map<String, Object> initKey() throws Exception { //获得对象 KeyPairGenerator 参数 RSA 1024个字节 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); //通过对象 KeyPairGenerator 获取对象KeyPair KeyPair keyPair = keyPairGen.generateKeyPair(); //通过对象 KeyPair 获取RSA公私钥对象RSAPublicKey RSAPrivateKey RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); //公私钥对象存入map中 Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } public static void main(String[] args) { Map<String, Object> keyMap; try { keyMap = initKey(); String publicKey = getPublicKey(keyMap); System.out.println(publicKey); String privateKey = getPrivateKey(keyMap); System.out.println(privateKey); } catch (Exception e) { e.printStackTrace(); } } } package com.kns.auth.utils.encrypt; import org.apache.commons.codec.binary.Base64; import sun.misc.BASE64Decoder; import javax.crypto.Cipher; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.*; /** * @Author:zhao-baolin * @Description: * @Date:Created in 2018/7/4 * @Modified By: */ public class RSAUtil { /** * 指定加密算法为DESede */ private static String ALGORITHM = "RSA/ECB/PKCS1Padding";//MD5withRSA///RSA/ECB/PKCS1Padding /** * 指定key的大小(64的整数倍,最小512位) */ private static int KEYSIZE = 1024; /* RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /* RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /* 公钥模量 */ public static String publicModulus = null; /* 公钥指数 */ public static String publicExponent = null; /* 私钥模量 */ public static String privateModulus = null; /* 私钥指数 */ public static String privateExponent = null; private static KeyFactory keyFactory = null; static { try { keyFactory = KeyFactory.getInstance("RSA"); } catch (NoSuchAlgorithmException ex) { System.out.println(ex.getMessage()); } } public RSAUtil() { try { generateKeyPairString(KEYSIZE); } catch (Exception e) { e.printStackTrace(); } } public RSAUtil(int keySize) { try { generateKeyPairString(keySize); } catch (Exception e) { e.printStackTrace(); } } /** * 生成密钥对字符串 */ private void generateKeyPairString(int keySize) throws Exception { /** RSA算法要求有一个可信任的随机数源 */ SecureRandom sr = new SecureRandom(); /** 为RSA算法创建一个KeyPairGenerator对象 */ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); /** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */ kpg.initialize(keySize, sr); /** 生成密匙对 */ KeyPair kp = kpg.generateKeyPair(); /** 得到公钥 */ Key publicKey = kp.getPublic(); /** 得到私钥 */ Key privateKey = kp.getPrivate(); /** 用字符串将生成的密钥写入文件 */ String algorithm = publicKey.getAlgorithm(); // 获取算法 KeyFactory keyFact = KeyFactory.getInstance(algorithm); BigInteger prime = null; BigInteger exponent = null; RSAPublicKeySpec keySpec = (RSAPublicKeySpec) keyFact.getKeySpec(publicKey, RSAPublicKeySpec.class); prime = keySpec.getModulus(); exponent = keySpec.getPublicExponent(); RSAUtil.publicModulus = HexUtil.bytes2Hex(prime.toByteArray()); RSAUtil.publicExponent = HexUtil.bytes2Hex(exponent.toByteArray()); RSAPrivateCrtKeySpec privateKeySpec = (RSAPrivateCrtKeySpec) keyFact.getKeySpec(privateKey, RSAPrivateCrtKeySpec.class); BigInteger privateModulus = privateKeySpec.getModulus(); BigInteger privateExponent = privateKeySpec.getPrivateExponent(); RSAUtil.privateModulus = HexUtil.bytes2Hex(privateModulus.toByteArray()); RSAUtil.privateExponent = HexUtil.bytes2Hex(privateExponent.toByteArray()); } /** * 根据给定的16进制系数和专用指数字符串构造一个RSA专用的公钥对象。 * * @param hexModulus 系数。 * @param hexPublicExponent 专用指数。 * @return RSA专用公钥对象。 */ public static RSAPublicKey getRSAPublicKey(String hexModulus, String hexPublicExponent) { if (isBlank(hexModulus) || 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.hex2Bytes(hexModulus); publicExponent = HexUtil.hex2Bytes(hexPublicExponent); } 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; } /** * 根据给定的系数和专用指数构造一个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; } /** * 根据给定的16进制系数和专用指数字符串构造一个RSA专用的私钥对象。 * * @param hexModulus 系数。 * @param hexPrivateExponent 专用指数。 * @return RSA专用私钥对象。 */ public static RSAPrivateKey getRSAPrivateKey(String hexModulus, String hexPrivateExponent) { if (isBlank(hexModulus) || 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.hex2Bytes(hexModulus); privateExponent = HexUtil.hex2Bytes(hexPrivateExponent); } 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; } /** * 根据给定的系数和专用指数构造一个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; } /** * 使用给定的公钥加密给定的字符串。 * * @param key 给定的公钥。 * @param plaintext 字符串。 * @return 给定字符串的密文。 */ public static String encryptString(Key key, String plaintext) { if (key == null || plaintext == null) { return null; } byte[] data = plaintext.getBytes(); try { byte[] en_data = encrypt(key, data); return new String(Base64.encodeBase64String(en_data)); // return new String(HexUtil.bytes2Hex(en_data)); } catch (Exception ex) { ex.printStackTrace(); } return null; } /** * 使用指定的公钥加密数据。 * * @param key 给定的公钥。 * @param data 要加密的数据。 * @return 加密后的数据。 */ public static byte[] encrypt(Key key, byte[] data) throws Exception { Cipher ci = Cipher.getInstance(ALGORITHM); ci.init(Cipher.ENCRYPT_MODE, key); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = ci.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = ci.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** * 使用给定的私钥解密给定的字符串。 * * @param key 给定的私钥 * @param encrypttext 密文 * @return 原文字符串。 */ public static String decryptString(Key key, String encrypttext) { if (key == null || isBlank(encrypttext)) { return null; } try { byte[] en_data = Base64.decodeBase64(encrypttext); byte[] data = decrypt(key, en_data); return new String(data); } catch (Exception ex) { ex.printStackTrace(); System.out.println(String.format("\"%s\" Decryption failed. Cause: %s", encrypttext, ex.getCause().getMessage())); } return null; } /** * 使用指定的私钥解密数据。 * * @param key 指定的私钥 * @param data 要解密的数据 * @return 原数据 * @throws Exception */ public static byte[] decrypt(Key key, byte[] data) throws Exception { Cipher ci = Cipher.getInstance(ALGORITHM); ci.init(Cipher.DECRYPT_MODE, key); // return ci.doFinal(data); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = ci.doFinal(data, offSet, MAX_DECRYPT_BLOCK); } else { cache = ci.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** * 判断非空字符串 * * @param cs 待判断的CharSequence序列 * @return 是否非空 */ private 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 PublicKey getPublicKey(String key) throws Exception { byte[] keyBytes; keyBytes = (new BASE64Decoder()).decodeBuffer(key); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } public static PrivateKey getPrivateKey(String key) throws Exception { byte[] keyBytes; keyBytes = (new BASE64Decoder()).decodeBuffer(key); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } }控制类:
@PostMapping("/ceshi") public Object ceshi(@RequestParam Map<String, Object> params)throws Exception { AjaxResult result = new AjaxResult(); String password=params.get("password").toString(); System.out.println("接收方用公钥加密后:" + password); // 私钥解密 PrivateKey privateKey=RSAUtil.getPrivateKey("私钥"); String oldSource = RSAUtil.decryptString(privateKey,password); System.out.print("发送方用私钥解密后:" + oldSource); return result; }前端代码:
<script type="text/javascript" src="https://passport.cnblogs.com/scripts/jsencrypt.min.js"></script> <script type="text/javascript"> //RSA测试 encryptPwd(); function encryptPwd(){ var publicKey ="公钥"; var encrypt = new JSEncrypt(); encrypt.setPublicKey(publicKey); // 加密 var password=encrypt.encrypt("加密数据"); var param={ "password":password } $.ajax({ type : 'post', url : '/competitor/ceshi', dataType: "json", data :param, success : function(result) { } }); } </script>