package com.whyc.util; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.math.BigInteger; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.*; /** * 简单加密解密 * * @author perry */ public class EncryptUtils { //盐 public static final char[] SALT = {'i', 's', 'a', 'o', 'f', 'f', 'i', 'c', 'a', 'l', 'p', 'r', 'o', 'j','e','c','t', '#', '$', '@', '#', '@'}; //rsa 长度 private static int KEY_LENGTH = 1024; /** * 加密 * * @param msg 内容 * @param key 密钥 * @param type 类型 * @return 密文 */ public static byte[] en(byte[] msg, char[] key, int type) { if (type == 1) { return enAES(msg, md5(StrUtils.merger(key, SALT), true)); } return enSimple(msg, key); } /** * 解密 * * @param msg 密文 * @param key 密钥 * @param type 类型 * @return 明文 */ public static byte[] de(byte[] msg, char[] key, int type) { if (type == 1) { return deAES(msg, md5(StrUtils.merger(key, SALT), true)); } return deSimple(msg, key); } /** * md5加密 * * @param str 字符串 * @return md5字串 */ public static byte[] md5byte(char[] str) { byte[] b = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] buffer = StrUtils.toBytes(str); md.update(buffer); b = md.digest(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return b; } /** * md5 * * @param str 字串 * @return 32位md5 */ public static char[] md5(char[] str) { return md5(str, false); } /** * md5 * * @param str 字串 * @param sh0rt 是否16位 * @return 32位/16位md5 */ public static char[] md5(char[] str, boolean sh0rt) { byte s[] = md5byte(str); if (s == null) { return null; } int begin = 0; int end = s.length; if (sh0rt) { begin = 8; end = 16; } char[] result = new char[0]; for (int i = begin; i < end; i++) { result = StrUtils.merger(result, Integer.toHexString((0x000000FF & s[i]) | 0xFFFFFF00).substring(6).toCharArray()); } return result; } /** * 加密 * * @param msg 加密报文 * @param start 开始位置 * @param end 结束位置 * @param key 密钥 * @return 加密后的字节 */ public static byte[] enSimple(byte[] msg, int start, int end, char[] key) { byte[] keys = IoUtils.merger(md5byte(StrUtils.merger(key, SALT)), md5byte(StrUtils.merger(SALT, key))); for (int i = start; i <= end; i++) { msg[i] = (byte) (msg[i] ^ keys[i % keys.length]); } return msg; } /** * 解密 * * @param msg 加密报文 * @param start 开始位置 * @param end 结束位置 * @param key 密钥 * @return 解密后的字节 */ public static byte[] deSimple(byte[] msg, int start, int end, char[] key) { byte[] keys = IoUtils.merger(md5byte(StrUtils.merger(key, SALT)), md5byte(StrUtils.merger(SALT, key))); for (int i = start; i <= end; i++) { msg[i] = (byte) (msg[i] ^ keys[i % keys.length]); } return msg; } /** * 加密 * * @param msg 加密报文 * @param key 密钥 * @return 加密后的字节 */ public static byte[] enSimple(byte[] msg, char[] key) { return enSimple(msg, 0, msg.length - 1, key); } /** * 解密 * * @param msg 加密报文 * @param key 密钥 * @return 解密后的字节 */ public static byte[] deSimple(byte[] msg, char[] key) { return deSimple(msg, 0, msg.length - 1, key); } /** * RSA公钥加密 * * @param str 加密字符串 * @param publicKey 公钥 * @return 密文 */ public static String enRSA(String str, String publicKey) { try { byte[] in = str.getBytes("UTF-8"); byte[] out = enRSA(in, publicKey); String outStr = Base64.getEncoder().encodeToString(out); return outStr; } catch (Exception e) { e.printStackTrace(); } return null; } /** * RSA公钥加密 * * @param msg 要加密的字节 * @param publicKey 公钥 * @return 解密后的字节 */ public static byte[] enRSA(byte[] msg, String publicKey) { try { //base64编码的公钥 byte[] decoded = Base64.getDecoder().decode(publicKey.getBytes("UTF-8")); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); //RSA加密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); return cipherDoFinal(cipher, msg, Cipher.ENCRYPT_MODE); } catch (Exception e) { e.printStackTrace(); } return null; } /** * RSA私钥解密 * * @param str 要解密的字符串 * @param privateKey 私钥 * @return 明文 */ public static String deRSA(String str, String privateKey) { try { //64位解码加密后的字符串 byte[] inputByte = Base64.getDecoder().decode(str.getBytes("UTF-8")); String outStr = new String(deRSA(inputByte, privateKey)); return outStr; } catch (Exception e) { e.printStackTrace(); } return null; } /** * RSA私钥解密 * * @param msg 要解密的字节 * @param privateKey 私钥 * @return 解密后的字节 */ public static byte[] deRSA(byte[] msg, String privateKey) { try { //base64编码的私钥 byte[] decoded = Base64.getDecoder().decode(privateKey.getBytes("UTF-8")); RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); //RSA解密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, priKey); return cipherDoFinal(cipher, msg, Cipher.DECRYPT_MODE); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 调用加密解密 * * @param cipher Cipher * @param msg 要加密的字节 * @param mode 解密/解密 * @return 结果 * @throws Exception Exception */ private static byte[] cipherDoFinal(Cipher cipher, byte[] msg, int mode) throws Exception { int in_length = 0; if (mode == Cipher.ENCRYPT_MODE) { in_length = KEY_LENGTH / 8 - 11; } else if (mode == Cipher.DECRYPT_MODE) { in_length = KEY_LENGTH / 8; } byte[] in = new byte[in_length]; byte[] out = new byte[0]; for (int i = 0; i < msg.length; i++) { if (msg.length - i < in_length && i % in_length == 0) { in = new byte[msg.length - i]; } in[i % in_length] = msg[i]; if (i == (msg.length - 1) || (i % in_length + 1 == in_length)) { out = IoUtils.merger(out, cipher.doFinal(in)); } } return out; } /** * 生成密钥对 * * @return 密钥信息 * @throws NoSuchAlgorithmException NoSuchAlgorithmException */ public static Map genKeyPair() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); keyPairGen.initialize(KEY_LENGTH, new SecureRandom()); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥 BigInteger publicExponent = publicKey.getPublicExponent(); BigInteger modulus = publicKey.getModulus(); String publicKeyString = new String(Base64.getEncoder().encode(publicKey.getEncoded())); String privateKeyString = new String(Base64.getEncoder().encode((privateKey.getEncoded()))); Map keyMap = new HashMap<>(); keyMap.put(0, publicKeyString); //0表示公钥 keyMap.put(1, privateKeyString); //1表示私钥 keyMap.put(2, modulus.toString(16));//modulus keyMap.put(3, publicExponent.toString(16));//e return keyMap; } /** * AES加密字符串 * * @param str 要加密的字符串 * @param key 密钥 * @return 加密结果 */ public static String enAES(String str, char[] key) { byte[] encrypted = null; try { encrypted = enAES(str.getBytes("utf-8"), key); } catch (Exception e) { e.printStackTrace(); } return encrypted == null ? null : Base64.getEncoder().encodeToString(encrypted); } /** * AES加密字节 * * @param msg 字节数组 * @param key 密钥 * @return 加密后的字节 */ public static byte[] enAES(byte[] msg, char[] key) { byte[] encrypted = null; try { byte[] raw = StrUtils.toBytes(key); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式" cipher.init(Cipher.ENCRYPT_MODE, skeySpec); encrypted = cipher.doFinal(msg); } catch (Exception e) { e.printStackTrace(); } return encrypted; } /** * AES解密 * * @param str 密文字串 * @param key 密钥 * @return 明文字串 */ public static String deAES(String str, char[] key) { String originalString = null; byte[] msg = Base64.getDecoder().decode(str); byte[] original = deAES(msg, key); try { originalString = new String(original, "utf-8"); } catch (Exception e) { } return originalString; } /** * AES解密 * * @param msg 要解密的字节 * @param key 密钥 * @return 明文字节 */ public static byte[] deAES(byte[] msg, char[] key) { byte[] original = null; try { byte[] raw = StrUtils.toBytes(key); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); original = cipher.doFinal(msg); } catch (Exception ex) { } return original; } /** * 随机字串 * * @param lenght 长度 * @return 字符数组 */ public static char[] randChar(int lenght) { char[] result = new char[lenght]; Character[] chars = new Character[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '_', '+', '.'}; List list = Arrays.asList(chars); Collections.shuffle(list); for (int i = 0; i < lenght; i++) { result[i] = list.get(i); } return result; } }