package com.whyc.util; import com.whyc.constant.YamlProperties; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.LinkedList; import java.util.List; public class RSAUtil { /** * 固定公私钥 */ private static final String publicKey = YamlProperties.publicKey; private static final String privateKey = YamlProperties.privateKey; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 384; public static final String fontSeparator = "&&&&&&&&&&"; /** * 获取密钥对 * * @return 密钥对 */ public static List getKeyPair() throws Exception { LinkedList list = new LinkedList<>(); KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(3072); KeyPair keyPair = generator.generateKeyPair(); String publicKey = Base64.encodeBase64String(keyPair.getPublic().getEncoded()); String privateKey = Base64.encodeBase64String(keyPair.getPrivate().getEncoded()); System.out.println("公钥:"+publicKey); System.out.println("私钥:"+privateKey); list.add(publicKey); list.add(privateKey); return list; } /** * 获取私钥 * * @param privateKey 私钥字符串 * @return */ public static PrivateKey getPrivateKey(String privateKey) { try { KeyFactory keyFactory = null; keyFactory = KeyFactory.getInstance("RSA"); byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey); return keyFactory.generatePrivate(keySpec); }catch (NoSuchAlgorithmException | InvalidKeySpecException e){ return null; } } /** * 获取私钥 * * @return */ public static PrivateKey getPrivateKey() { try { KeyFactory keyFactory = null; keyFactory = KeyFactory.getInstance("RSA"); byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes()); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey); return keyFactory.generatePrivate(keySpec); }catch (NoSuchAlgorithmException | InvalidKeySpecException e){ return null; } } /** * 获取公钥 * * @param publicKey 公钥字符串 * @return */ public static PublicKey getPublicKey(String publicKey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey); return keyFactory.generatePublic(keySpec); } /** * 获取公钥 * * @return */ public static PublicKey getPublicKey(){ try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes()); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey); return keyFactory.generatePublic(keySpec); }catch (Exception e){ return null; } } /** * RSA加密 * * @param data 待加密数据 * @param publicKey 公钥 * @return */ public static String encrypt(String data, PublicKey publicKey) { try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); int inputLen = data.getBytes().length; 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.getBytes(), offset, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset); } out.write(cache, 0, cache.length); i++; offset = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); // 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串 // 加密后的字符串 return new String(Base64.encodeBase64String(encryptedData)); }catch (Exception e){ return null; } } /** * RSA解密 * * @param data 待解密数据 * @param privateKey 私钥 * @return */ public static String decrypt(String data, PrivateKey privateKey) { try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] dataBytes = Base64.decodeBase64(data); int inputLen = dataBytes.length; 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(dataBytes, offset, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(dataBytes, offset, inputLen - offset); } out.write(cache, 0, cache.length); i++; offset = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); // 解密后的内容 return new String(decryptedData, "UTF-8"); }catch (Exception e){ return null; } } /** * RSA解密 * * @param data 待解密数据 * @return */ public static String decrypt(String data) { try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, getPrivateKey()); byte[] dataBytes = Base64.decodeBase64(data); int inputLen = dataBytes.length; 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(dataBytes, offset, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(dataBytes, offset, inputLen - offset); } out.write(cache, 0, cache.length); i++; offset = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); // 解密后的内容 return new String(decryptedData, "UTF-8"); }catch (Exception e){ return null; } } /** * 前端加密数据RSA[明文+MD5(明文)]解密为明文和MD5[明文] * @param frontEncryptData * @return */ public static String[] decryptFront(String frontEncryptData,String separatorStr){ String[] dataArr = new String[2]; String dataMD5Mix = RSAUtil.decrypt(frontEncryptData, RSAUtil.getPrivateKey()); int index = dataMD5Mix.lastIndexOf(separatorStr); String data = dataMD5Mix.substring(0, index); String dataMD5 = dataMD5Mix.substring(index+separatorStr.length()); dataArr[0] = data; dataArr[1] = dataMD5; return dataArr; } /** * 先URL解码,再进行密文解析[rsa(明文+md5)] */ public static String[] decryptFrontP(String frontEncryptData,String separatorStr){ try { frontEncryptData = URLDecoder.decode(frontEncryptData, "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } String[] dataArr = new String[2]; String dataMD5Mix = RSAUtil.decrypt(frontEncryptData, RSAUtil.getPrivateKey()); if(dataMD5Mix!=null){ int index = dataMD5Mix.lastIndexOf(separatorStr); String data = dataMD5Mix.substring(0, index); String dataMD5 = dataMD5Mix.substring(index+separatorStr.length()); dataArr[0] = data; dataArr[1] = dataMD5; } return dataArr; } public static void main(String[] args) { try { //String word = "123456"; //String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPpJ3j+SHQ69lqq+ShV7deA40Y+8rYra6rr4ReOJ+UE7ek8tsJJrcy1xMO1SophJdHXXwSNbZWhnJW9GlIq1Um6IplkwFc/AtyoeJDP3EJtUZgI5H6fSz0BPLFHn18C0Nxz1Br109U07DqQdMsarcBmKXYQw+2oZOz0KpA5b0FawIDAQAB"; //String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAI+kneP5IdDr2Wqr5KFXt14DjRj7ytitrquvhF44n5QTt6Ty2wkmtzLXEw7VKimEl0ddfBI1tlaGclb0aUirVSboimWTAVz8C3Kh4kM/cQm1RmAjkfp9LPQE8sUefXwLQ3HPUGvXT1TTsOpB0yxqtwGYpdhDD7ahk7PQqkDlvQVrAgMBAAECgYA8ASdX4W2n6a4kKnRSleLqqg8aHazqAPvTinmAJqU65VW02SJ42yxyV3gFnTSErXfIfxviO3/U+0ruWiFVEwV5oDEh0dOd+HHGm4YzFXIRglMeRBgLuVJ+owzoVDwZstiIBa69DIjaJtmpSf5FjwxAth+gtCv3e11IXHraKN720QJBAMPMB1WtmpRGYHxWVYjKSL+RGw+h3gMQLk3exZjhmYRlXuqfVZ2Zol+NazDc59K5f+geMdJ0/X2kKnKLVjWzYHMCQQC7z1cFYswtLemxGfj+dwlVC01VL4pKa7HGHl/FAQ2UNYZY2d5hE/nXYbTpfI0gMowX926/aFpia7NbAUJO7WEpAkAyUFa+LJthaOhYazMVsK2bFKW4kabkcJ8Fga6TR73UaNxIPGOa2SUBmuylpM6ptuNoeYHiDBAr3ijOQIIJ0KuDAkBy9fPahCNe9F+73J4hhVPdDtIDdto7u7hSAX215XMeabUW5iXNXqDsSg6nbWolb0t50CemWoYZALwE1Lx1+7AhAkEAoZtFt+2skjAxHEqNUye4vKBqB2Ng/wmfitCfT34lXWQsxs4BGk/8eQMzkam9bcB7FcinolxHF/1UjsUYpI+AgA=="; //List keyPair = getKeyPair(); //String encryptWord = encrypt(word, getPublicKey(keyPair.get(0))); //System.out.println("加密后的字符串:"+encryptWord); //String encryptWord = "NTDEt29l3QqDjgbK5AToix14GQNMi2qPDgsIy7JQf0586wEhOr6LgQ3YuZo9gEYLgmRxdOtxTcVCMugIJnXr6xukoopYfdH7epnQlszMYcM73a7mOrI1DJQA8%2B7AnMkm0s3X3GR7CdpT2OHrdogOAywFWhBirETaeY36ZH%2FOrXQ%3D"; //encryptWord=URLDecoder.decode(encryptWord, "utf-8"); String encrypt = encrypt("hELEEWWEEr9Lu6HgEvttjj8vYhy3ID+PqPbumuXhcHhe", getPublicKey()); System.out.println(encrypt); } catch (Exception e) { e.printStackTrace(); } } }