From 737ba5223c9c6193f4cd0f185512e506677b864e Mon Sep 17 00:00:00 2001 From: xiangwb Date: Mon, 20 Nov 2017 17:04:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0rsa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- boot-service/pom.xml | 6 + .../main/java/com/xwbing/util/RSAUtil.java | 255 ++++++++++++++++++ .../com/xwbing/controller/TestControl.java | 14 + .../src/main/resources/rsa_private_key.pem | 15 ++ .../src/main/resources/rsa_public_key.pem | 6 + 5 files changed, 296 insertions(+) create mode 100644 boot-service/src/main/java/com/xwbing/util/RSAUtil.java create mode 100644 boot-web/src/main/resources/rsa_private_key.pem create mode 100644 boot-web/src/main/resources/rsa_public_key.pem diff --git a/boot-service/pom.xml b/boot-service/pom.xml index 8b155c3..7543839 100644 --- a/boot-service/pom.xml +++ b/boot-service/pom.xml @@ -66,6 +66,12 @@ javase ${zxing.version} + + + org.bouncycastle + bcprov-jdk16 + 1.45 + javax.servlet diff --git a/boot-service/src/main/java/com/xwbing/util/RSAUtil.java b/boot-service/src/main/java/com/xwbing/util/RSAUtil.java new file mode 100644 index 0000000..f2f4dea --- /dev/null +++ b/boot-service/src/main/java/com/xwbing/util/RSAUtil.java @@ -0,0 +1,255 @@ +package com.xwbing.util; + +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure; +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.*; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.RSAPrivateKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * 项目名称: boot-module-demo + * 创建时间: 2017/11/20 16:26 + * 作者: xiangwb + * 说明: + */ +public class RSAUtil { + + /** + * 从文件中加载公钥 测试的时候使用 + * + * @return + * @throws Exception + */ + public static RSAPublicKey loadPublicKey() throws Exception { + try { + String filePath = RSAUtil.class.getClassLoader() + .getResource("rsa_public_key.pem").getPath(); + InputStream in = new FileInputStream(filePath); + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + String readLine; + StringBuilder sb = new StringBuilder(); + while ((readLine = br.readLine()) != null) { + if (readLine.charAt(0) == '-') { + continue; + } else { + sb.append(readLine); + sb.append('\r'); + } + } + br.close(); + return loadPublicKey(sb.toString()); + } catch (IOException e) { + throw new Exception("公钥数据流读取错误"); + } catch (NullPointerException e) { + throw new Exception("公钥输入流为空"); + } + } + + /** + * 从字符串中加载公钥 + * + * @param publicKeyStr 公钥数据字符串 + * @throws Exception 加载公钥时产生的异常 + */ + public static RSAPublicKey loadPublicKey(String publicKeyStr) + throws Exception { + try { + BASE64Decoder base64Decoder = new BASE64Decoder(); + byte[] buffer = base64Decoder.decodeBuffer(publicKeyStr); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); + return (RSAPublicKey) keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException e) { + throw new Exception("无此算法"); + } catch (InvalidKeySpecException e) { + throw new Exception("公钥非法"); + } catch (IOException e) { + throw new Exception("公钥数据内容读取错误"); + } catch (NullPointerException e) { + throw new Exception("公钥数据为空"); + } + } + + /** + * 从文件中加载私钥 测试的时候使用 私钥文件名 + * + * @return 是否成功 + * @throws Exception + */ + public static RSAPrivateKey loadPrivateKey() throws Exception { + try { + String filePath = RSAUtil.class.getClassLoader() + .getResource("rsa_private_key.pem").getPath(); + InputStream in = new FileInputStream(filePath); + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + String readLine; + StringBuilder sb = new StringBuilder(); + while ((readLine = br.readLine()) != null) { + if (readLine.charAt(0) == '-') { + continue; + } else { + sb.append(readLine); + sb.append('\r'); + } + } + br.close(); + return loadPrivateKey(sb.toString()); + } catch (IOException e) { + throw new Exception("私钥数据读取错误"); + } catch (NullPointerException e) { + throw new Exception("私钥输入流为空"); + } + } + + /** + * 功能描述: 从字符串中加载私钥 + * + * @param privateKeyStr + * @return + * @throws Exception + */ + public static RSAPrivateKey loadPrivateKey(String privateKeyStr) + throws Exception { + try { + BASE64Decoder base64Decoder = new BASE64Decoder(); + byte[] priKeyData = base64Decoder.decodeBuffer(privateKeyStr); + // 读pkcs#8码 + // PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(priKeyData); + // 读pkcs#1码(传统私钥格式) + RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure( + (ASN1Sequence) ASN1Sequence.fromByteArray(priKeyData)); + RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec( + asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent()); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return (RSAPrivateKey) keyFactory.generatePrivate(rsaPrivKeySpec); + } catch (NoSuchAlgorithmException e) { + throw new Exception("无此算法"); + } catch (InvalidKeySpecException e) { + throw new Exception("私钥非法"); + } catch (IOException e) { + throw new Exception("私钥数据内容读取错误"); + } catch (NullPointerException e) { + throw new Exception("私钥数据为空"); + } + } + + /** + * 加密过程 + * + * @param publicKey 公钥 明文数据 + * @return + * @throws Exception 加密过程中的异常信息 + */ + public static String encrypt(RSAPublicKey publicKey, String data) + throws Exception { + if (publicKey == null) { + throw new Exception("加密公钥为空, 请设置"); + } + byte[] plainTextData = data.getBytes(); + Cipher cipher; + try { + cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");// 得到Cipher对象来实现对源数据的RSA加密 + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] output = cipher.doFinal(plainTextData);// 执行加密操作 + BASE64Encoder base64Encoder = new BASE64Encoder(); + return base64Encoder.encode(output);// Base64编码成字符串 + } catch (NoSuchAlgorithmException e) { + throw new Exception("无此加密算法"); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + return null; + } catch (InvalidKeyException e) { + throw new Exception("加密公钥非法,请检查"); + } catch (IllegalBlockSizeException e) { + throw new Exception("明文长度非法"); + } catch (BadPaddingException e) { + throw new Exception("明文数据已损坏"); + } + } + + /*** + * 默认加密方式 + * + * @param data + * @return + * @throws Exception + */ + public static String encrypt(String data) throws Exception { + return encrypt(loadPublicKey(), data); + } + + /** + * 解密过程 + * + * @param privateKey 私钥 密文数据 + * @return 明文 + * @throws Exception 解密过程中的异常信息 + */ + public static String decrypt(RSAPrivateKey privateKey, String data) throws Exception { + if (privateKey == null) { + throw new Exception("解密私钥为空, 请设置"); + } + BASE64Decoder base64Decoder = new BASE64Decoder(); + byte[] cipherData = base64Decoder.decodeBuffer(data); + Cipher cipher; + try { + cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] output = cipher.doFinal(cipherData); + return new String(output); + } catch (NoSuchAlgorithmException e) { + throw new Exception("无此解密算法"); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + return null; + } catch (InvalidKeyException e) { + throw new Exception("解密私钥非法,请检查"); + } catch (IllegalBlockSizeException e) { + throw new Exception("密文长度非法"); + } catch (BadPaddingException e) { + throw new Exception("密文数据已损坏"); + } + } + + /** + * 功能描述: 默认解密方式 + * + * @param data + * @return + * @throws Exception + */ + public static String decrypt(String data) throws Exception { + return decrypt(loadPrivateKey(), data); + } + + public static void main(String[] args) throws Exception { + String en = testJiami();// 密文 + String de = testJiemi(en);// 明文 + System.out.println(de); + } + + private static String testJiami() throws Exception { + String plainText = encrypt(loadPublicKey(), "123456"); + System.out.println("加密结果:" + plainText); + return plainText; + } + + private static String testJiemi(String str) throws Exception { + String plainText = decrypt(loadPrivateKey(), str); + System.out.println("解密结果:" + plainText); + return plainText; + } +} diff --git a/boot-web/src/main/java/com/xwbing/controller/TestControl.java b/boot-web/src/main/java/com/xwbing/controller/TestControl.java index 3bd6d4a..8caeec3 100644 --- a/boot-web/src/main/java/com/xwbing/controller/TestControl.java +++ b/boot-web/src/main/java/com/xwbing/controller/TestControl.java @@ -4,10 +4,12 @@ import com.alibaba.fastjson.JSONObject; import com.xwbing.annotation.LogInfo; import com.xwbing.domain.entity.ExpressInfo; import com.xwbing.domain.entity.vo.ExpressInfoVo; +import com.xwbing.exception.BusinessException; import com.xwbing.redis.RedisService; import com.xwbing.service.ExpressDeliveryService; import com.xwbing.service.QRCodeZipService; import com.xwbing.util.JSONObjResult; +import com.xwbing.util.RSAUtil; import com.xwbing.util.RestMessage; import io.swagger.annotations.Api; import org.apache.commons.lang3.StringUtils; @@ -94,4 +96,16 @@ public class TestControl { RestMessage restMessage = qrCodeZipService.batchGetImage(response, names, fileName); return JSONObjResult.toJSONObj(restMessage); } + + @LogInfo("rsa") + @GetMapping("rsa") + public void rsa() { + try { + String en = RSAUtil.encrypt("123456"); + String de = RSAUtil.decrypt(en); + System.out.println(de); + } catch (Exception ex) { + throw new BusinessException(ex.getMessage()); + } + } } diff --git a/boot-web/src/main/resources/rsa_private_key.pem b/boot-web/src/main/resources/rsa_private_key.pem new file mode 100644 index 0000000..00b0989 --- /dev/null +++ b/boot-web/src/main/resources/rsa_private_key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQC97mOEdHwOP8lRTcBnPecTU7OsJ225/7VlMTTYPL2p4XBPmspO +I1IxqQN0m4ULoAfb25S6xB8GpsPG63db+cGKmJUAO0KioVev/9r+9P6kKvbstjIQ +mjREvJVmAHEjN6I1Pj61D0Pd3RnkafN+JGWWenUTuiSdsOrfgDHMc4EysQIDAQAB +AoGBALKUVlXQAGSVbQBZDrMD7SSq6qDPYcgkubWvknROiDYWlbcDX3wgkcPHmkwl +fe70RO9fgnQoutNSMXnzI4MDTgkWJBmThJV/EZZ6GRgFugdsjwYjfRJc184PHJlC +L4xSWh9NV6gOnrdr7JlsR/Tg3DN2XM+R/rieZrr1Fg2I0JGRAkEA8SYEYMnyM7Dw +FQhewUPDu328SFcifW/A4HIFFYaJfp9qJqrgJ7p8iPC4JKrhVS/B1gWV+pkPxrYu +sfizMhdluwJBAMmg30WmAI/J22eb5NsZB4bcgO7MIecVIirUdVAd1wS+2iZ0c3r5 ++aNg7/GW+mYDk5bB/c+0dPu1DxSDTb1kLIMCQETRs6gnmb5UvX9THy+Kdj54mJYQ +f+BKV0H2aCsHdQ+00OduFoBgARBXmkWkmp/j/C5m87FLoyvzbAoQTpt5/+cCQFe+ +UmuU2hm41mo4RVezhLsDqnhBDV/qqnvJCWRcF/5Qr86cTsTtk92tib2w3jcWx1uM +AFArT91Z5b4fhe0tctECQQCq1tWQZOXX+m7/afh9v6SoP8OENRBd8/PUMs8N+TXm +PflFMPvuGYodH/6G/doQX3QgQUAWHMfxjFIE0DCkAbDJ +-----END RSA PRIVATE KEY----- diff --git a/boot-web/src/main/resources/rsa_public_key.pem b/boot-web/src/main/resources/rsa_public_key.pem new file mode 100644 index 0000000..4d7c369 --- /dev/null +++ b/boot-web/src/main/resources/rsa_public_key.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC97mOEdHwOP8lRTcBnPecTU7Os +J225/7VlMTTYPL2p4XBPmspOI1IxqQN0m4ULoAfb25S6xB8GpsPG63db+cGKmJUA +O0KioVev/9r+9P6kKvbstjIQmjREvJVmAHEjN6I1Pj61D0Pd3RnkafN+JGWWenUT +uiSdsOrfgDHMc4EysQIDAQAB +-----END PUBLIC KEY-----