package com.zehong.web.controller.api; import javax.crypto.Cipher; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Base64; import java.util.List; /** * 平台自定义加密算法规则 和示例 * * @Author wangjian * @Date 2023/8/15 * @Version 1.0 */ public class RsaToClient { private String publicKey; private String privatekey; public RsaToClient(String privateKey, String publicKey) { this.privatekey = privateKey; this.publicKey = publicKey; } public RsaToClient() { } private static final String RSA_ALGORITHM = "RSA"; /** * 生成RSA密钥对 * * @return RSA密钥对 */ @Deprecated public KeyPair generateKeyPair() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM); keyPairGenerator.initialize(2048); // 密钥大小为2048位 return keyPairGenerator.generateKeyPair(); } /** * 使用公钥加密数据 * * @param data 待加密的数据 * @param publicKey 公钥 * @return 加密后的数据 */ public String encrypt(String data, PublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(encryptedData); } /** * 公钥字符串 转换为公钥 * * @param publicKeyString */ public PublicKey generateRSAPublicKey(String publicKeyString) throws NoSuchAlgorithmException, InvalidKeySpecException { byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } /** * 对小字符串进行加密 小于245字节的字符串 * * @param data */ public String encrypt(String data, String publicKeyString) throws Exception { PublicKey publicKey = generateRSAPublicKey(publicKeyString); Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(encryptedData); } public String encrypt2(byte[] data, String publicKeyString) throws Exception { PublicKey publicKey = generateRSAPublicKey(publicKeyString); Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedData = cipher.doFinal(data); return Base64.getEncoder().encodeToString(encryptedData); } /** * 对大字符串进行加密 */ public String encryptMaxString(String data, String publicKeyString) throws Exception { byte[] bytes = data.getBytes(StandardCharsets.UTF_8); Object[] objects = splitByteArr(bytes, 245); String codeAll = ""; //依次加密 for (int i = 0; i < objects.length; i++) { byte[] temp = (byte[]) objects[i]; // String encryptedData = encrypt(new String(temp, "UTF-8"), publicKeyString); String encryptedData = encrypt2(temp, publicKeyString); codeAll += "@@" + encryptedData; } return codeAll; } /** * 使用私钥解密数据 * * @param encryptedData 加密后的数据 * @param privateKey 私钥 * @return 解密后的数据 */ public String decrypt(String encryptedData, PrivateKey privateKey) throws Exception { byte[] decodedData = Base64.getDecoder().decode(encryptedData); Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedData = cipher.doFinal(decodedData); return new String(decryptedData, StandardCharsets.UTF_8); } /** * 私钥字符串 转换为 私钥对象 * * @param privateKeyString */ public PrivateKey generateRSAPrivateKey(String privateKeyString) throws NoSuchAlgorithmException, InvalidKeySpecException { byte[] decode = Base64.getDecoder().decode(privateKeyString); PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decode); return KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec); } /** * 对加密字符串 进行解密 * * @param encryptedData * @param privateKeyString */ public String decrypt(String encryptedData, String privateKeyString) throws Exception { PrivateKey privateKey = generateRSAPrivateKey(privateKeyString); byte[] decodedData = Base64.getDecoder().decode(encryptedData); Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedData = cipher.doFinal(decodedData); return new String(decryptedData, StandardCharsets.UTF_8); } public byte[] decryptBytes(String encryptedData, String privateKeyString) throws Exception { PrivateKey privateKey = generateRSAPrivateKey(privateKeyString); byte[] decodedData = Base64.getDecoder().decode(encryptedData); Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedData = cipher.doFinal(decodedData); return decryptedData; } /** * 对大字符串加密字符串 进行解密 */ public String decryptMaxString(String encryptedData, String privateKeyString) throws Exception { String decodeAll = ""; byte[] bytes = new byte[0]; String[] split = encryptedData.split("@@"); ByteArrayOutputStream out = new ByteArrayOutputStream(); for (String s : split) { if ("".equals(s) == false) { //解密 // String decryptedData = decrypt(s,privateKeyString); byte[] outBytes = decryptBytes(s,privateKeyString); out.write(outBytes); // decodeAll += decryptedData; } } return new String(out.toByteArray(), StandardCharsets.UTF_8); // return decodeAll; } public static void main(String[] args) throws Exception { ////示例2 现有密钥进行加密 解密 //企业ID为一 燃气集团 生成 加密 公钥 私钥 String publicKeyString = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnxZeDNdIm9/HGsm+LuL8NvycGbabVkOr4gJv/LfNkDPItqj2DTGpZgrCKTuPu0G0lTvjIxvoX5yibel3NoPqmohEZ6on3JF4MWt7KocArXaWkcip92Mrk1s32YHHjzo0Db8QJU6Ct2ldCaKshX3RlWrFYDXjOSbMvYA7wc2DZj1Q7q/1kBhSBqTVHc7HWwYYm/OWtBFXLZ6KPvc+snpNEW2iVKoea+t5okz5NzwifJV7+adYQEIPIWerfssQhs6TLQrkMGf1J2IfdMOG1srSIti4Pxla4UGyfqvUxQ+601yGjh/TCeIGSJr8oPj9u6eB2nQ95Ne2CJ/lCWuxd7DzNQIDAQAB"; String privateKeyString = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCfFl4M10ib38cayb4u4vw2/JwZtptWQ6viAm/8t82QM8i2qPYNMalmCsIpO4+7QbSVO+MjG+hfnKJt6Xc2g+qaiERnqifckXgxa3sqhwCtdpaRyKn3YyuTWzfZgcePOjQNvxAlToK3aV0JoqyFfdGVasVgNeM5Jsy9gDvBzYNmPVDur/WQGFIGpNUdzsdbBhib85a0EVctnoo+9z6yek0RbaJUqh5r63miTPk3PCJ8lXv5p1hAQg8hZ6t+yxCGzpMtCuQwZ/UnYh90w4bWytIi2Lg/GVrhQbJ+q9TFD7rTXIaOH9MJ4gZImvyg+P27p4HadD3k17YIn+UJa7F3sPM1AgMBAAECggEAIsmmWVJ+Wy+M/2ucPe5+zptgmzLWNv/nRy3XRUEAH4djXaYG4A27CEhT+uY+YOlWTsfgvF2u67F5x2UlH3OrSo1/v9dyjgX1bYEeVsdcu5HSDSD/Icy6y6dHyDVb6RMGLPdZ1X6ckPTmVmQPK8W+ndjSPl6qSGYWoV24M4H4ONPYonmQoL7P4DR7jHDbCzqoaBYcrxZT6K52apGKOBqzRrRxlrFPPScvVwaRSXWSYZcN18K9z7yiXwFf1nwBizRGFt6tvchwgYpjxLLON8qcxcLvtcvmrqAqIdIf9HlPOHnkwjgFqNFwXxI48e26gwV2kBJRajrskyusFlbIATv1ZQKBgQDmj27N2Gx08G3dvGQYnTw3rDBbWn7F4ZXe5f6wNAv5kFr/VuIB046u2jQAdWtUmeM5eRd6PeTE4OvX7FuC/o2m/BaKhNWP6No9yzKwuyCNj4dj98G9H5vneOa3RY3F1ma/Bd8hoY6QC/NQDoabp4wFKjYbcD9uHsdLD0S9x405nwKBgQCwpA+HY13A/MVXgTTQ2+A24b+cE5VobOnoJ2ad3NuyYx71CQ4nu9BORSkh6fB2A0DkHY1/wOexi1qILFlwABWZRFKRkwY7+vAJjLlaG5QtvUixWgQ0HvNlWC/e6XfsWJjeKcJmsBlrnfI3uZvxfXveDVlHOfF+e//zKzUTYJzKqwKBgHyDX6K5S7FHmv3R3PjSCZBDZIYhdC9nqamL6iS8pu7rP8l/4WR9HSRe4RCSWRmCVg1W0RAKVv7gPV4J3k37LQLOR1odbLxgU2Rl1YVOOcFZjxO03KNHa8nxKCA35t298RUelacy+avfWFKW1alALcUoS7o7v3W4F4b4wvX+y80fAoGAfmq77mIv++krdseyu/NQkRaZYiMl35lrAcoJB9vDo/SKeEWlyswAdbPLj0j03hDQBTIdTZwKdadNAH30+FInIwyhpyu4335lAgCjuphYQS/hcYQB1Cd+fD5T7E3clNqHdSAf0Awh9UIR0s3UjE0JNE8LYQ1YBvTJpgd7McYIEIcCgYEAsKgI481TPfjrCML0bjZ+d5O8fObFcQup2CzAlXvZtQrM62/Siubwta7IRiZK6yeMbU4uWeZxNBdPIE8Dd5HBFRHiJiD8uB3gdq91YxQYmbu1i37MxueAAlGGpD6Ds5OZZ6+PZZw2SGcUMgY2Y06eqVyxfbdCWuA8sQ4oxyb8DmI="; RsaToClient rsa = new RsaToClient(privateKeyString, publicKeyString); System.out.println("publickey=" + publicKeyString); System.out.println("privateKey=" + privateKeyString); //封装员工证书模型 // WorkCertModel model = new WorkCertModel(); // model.setApprovalNumber("冀7823478247977"); // model.setCertProfessionType("特种设备作业人员(市场监督管理总局颁发)"); // model.setApprovalDate("2004-05-22"); // model.setAssessGroup("省住建厅"); // model.setWorkerCode("workcode"); // model.setCertificateLevel("1"); // model.setCertSendDate("2004-05-22"); // model.setCertDateEnd("2004-07-22"); // model.setCertificateCode("3000550001"); // //// 组装加密数据结构 (这里根据接口参数进行调整组装格式) // List<WorkCertModel> list = new ArrayList<>(); // list.add(model); // WorkerCertDirectDTO dd = new WorkerCertDirectDTO(); // dd.setList(list); // String jsonObj = JSONObject.toJSONString(dd); String Str = "[{\"codeExtsys\":\"54-130274-100096\",\"eqEightNum\":\"1\",\"eqFiveNum\":\"0\",\"eqFourNum\":\"1\",\"eqNineNum\":\"0\",\"eqOneNum\":\"1\",\"eqSevenNum\":\"0\",\"eqSixNum\":\"1\",\"eqTenNum\":\"0\",\"eqThreeNum\":\"1\",\"eqTwoNum\":\"0\",\"gasType\":\"030100\",\"gcState\":\"100200\",\"gcTypeSecond\":\"130100\",\"lastRefillDate\":\"2022-06-15\",\"name\":\"唐山海港宏声家电维修部\",\"point\":\"118.138649 39.636066\",\"region\":\"130274\",\"sceneModels\":[{\"code\":\"110100\"}],\"startDate\":\"2019-11-04\",\"workplace\":\"海港港欣华府东侧底商\"}]"; // String Str = "[{\"codeExtsys\":\"54-130274-100193\",\"eqEightNum\":\"1\",\"eqFiveNum\":\"0\",\"eqFourNum\":\"1\",\"eqNineNum\":\"0\",\"eqOneNum\":\"1\",\"eqSevenNum\":\"0\",\"eqSixNum\":\"1\",\"eqTenNum\":\"0\",\"eqThreeNum\":\"1\",\"eqTwoNum\":\"0\",\"gasType\":\"030300\",\"gcState\":\"100200\",\"gcTypeSecond\":\"130100\",\"lastRefillDate\":\"2023-03-14\",\"name\":\"唐山东冶实业有限责任公司\",\"point\":\"118.130318 39.617767\",\"region\":\"130274\",\"sceneModels\":[{\"code\":\"110500\"}],\"startDate\":\"2017-11-18\",\"workplace\":\"乐亭县临港产业聚集区\"}]"; // String Str = "[{\"codeExtsys\":\"54-130274-100214\",\"eqEightNum\":\"1\",\"eqFiveNum\":\"0\",\"eqFourNum\":\"1\",\"eqNineNum\":\"0\",\"eqOneNum\":\"1\",\"eqSevenNum\":\"0\",\"eqSixNum\":\"1\",\"eqTenNum\":\"0\",\"eqThreeNum\":\"1\",\"eqTwoNum\":\"0\",\"gasType\":\"030300\",\"gcState\":\"100200\",\"gcTypeSecond\":\"130100\",\"lastRefillDate\":\"2022-09-09\",\"name\":\"唐山市荣辉货物运输有限公司\",\"point\":\"118.42598 39.789928\",\"region\":\"130274\",\"sceneModels\":[{\"code\":\"110100\"}],\"startDate\":\"2021-06-13\",\"workplace\":\"唐山海港开发区12号路\"}]"; Str += Str + Str; //加密 //11130200001 企业ID=1的 企业CODE 这个月header参数是对应的 String data = "11130281007@" + Str; System.out.println("data=" + data); System.out.println("数据" + Str); // 加密的算法有长度限制 不再采用配合其他加密算法来解决了 直接切断处理加密 String encryptedData = rsa.encryptMaxString(data, publicKeyString); System.out.println("加密后的数据:" + encryptedData); //解密 String decryptedData = rsa.decryptMaxString(encryptedData, privateKeyString); System.out.println("解密后的数据:" + decryptedData); } /** * 将byte数组按照指定大小分割成多个数组 * * @param bytes 要分割的byte数组 * @param subSize 分割的块大小 单位:字节 * @return 指定大小的byte数组 */ public static Object[] splitByteArr(byte[] bytes, int subSize) { int count = bytes.length % subSize == 0 ? bytes.length / subSize : bytes.length / subSize + 1; List<List<Byte>> subAryList = new ArrayList<List<Byte>>(); for (int i = 0; i < count; i++) { int index = i * subSize; List<Byte> list = new ArrayList<Byte>(); int j = 0; while (j < subSize && index < bytes.length) { list.add(bytes[index++]); j++; } subAryList.add(list); } Object[] subAry = new Object[subAryList.size()]; for (int i = 0; i < subAryList.size(); i++) { List<Byte> subList = subAryList.get(i); byte[] subAryItem = new byte[subList.size()]; for (int j = 0; j < subList.size(); j++) { subAryItem[j] = subList.get(j); } subAry[i] = subAryItem; } return subAry; } }