From 87799b603431a434b694561134cbd2f7bff2cc7d Mon Sep 17 00:00:00 2001 From: xiongfeng Date: Mon, 20 Jun 2022 18:16:48 +0800 Subject: [PATCH] =?UTF-8?q?rsa=E5=8A=A0=E5=AF=86=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/xf/basedemo/common/utils/RSAUtils.java | 185 ++++++++++++++++++ .../cn/xf/basedemo/config/GlobalConfig.java | 28 +++ src/main/resources/application-dev.yml | 5 + src/main/resources/application.yml | 19 +- 4 files changed, 228 insertions(+), 9 deletions(-) create mode 100644 src/main/java/cn/xf/basedemo/common/utils/RSAUtils.java create mode 100644 src/main/java/cn/xf/basedemo/config/GlobalConfig.java diff --git a/src/main/java/cn/xf/basedemo/common/utils/RSAUtils.java b/src/main/java/cn/xf/basedemo/common/utils/RSAUtils.java new file mode 100644 index 0000000..7d440c1 --- /dev/null +++ b/src/main/java/cn/xf/basedemo/common/utils/RSAUtils.java @@ -0,0 +1,185 @@ +package cn.xf.basedemo.common.utils; + +import org.apache.tomcat.util.codec.binary.Base64; +import org.apache.tomcat.util.http.fileupload.IOUtils; +import javax.crypto.Cipher; +import java.io.ByteArrayOutputStream; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashMap; +import java.util.Map; + +/** + * @program: xf-boot-base + * @ClassName RSAUtils + * @description: + * @author: xiongfeng + * @create: 2022-06-20 10:37 + **/ +public class RSAUtils { + + //算法类型 + private static final String RSA = "RSA"; + + //字符编码类型 + private static final String CHARSET = "UTF-8"; + + //加密长度 + private static final int ENCRYPT_SIZE = 1024; + + + /** + * 创建rsa密匙对 + * @return + */ + private static Map createEncryptKey(){ + + KeyPairGenerator kpg; + try { + kpg = KeyPairGenerator.getInstance(RSA); + }catch (Exception e){ + throw new IllegalArgumentException(); + } + kpg.initialize(ENCRYPT_SIZE); + KeyPair keyPair = kpg.generateKeyPair(); + PublicKey aPublic = keyPair.getPublic(); + String publicKey = Base64.encodeBase64URLSafeString(aPublic.getEncoded()); + + PrivateKey aPrivate = keyPair.getPrivate(); + String privateKey = Base64.encodeBase64URLSafeString(aPrivate.getEncoded()); + + Map map =new HashMap<>(); + + map.put("publicKey", publicKey); + map.put("privateKey", privateKey); + + return map; + } + + /** + * 获取ras公匙 + * @param publicKeyStr 公匙加密字符串 + * @return + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + */ + public static RSAPublicKey getPublicKey(String publicKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException { + // 通过X509编码的Key指令获得公钥对象 + KeyFactory keyFactory = KeyFactory.getInstance(RSA); + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64URLSafe(publicKeyStr)); + RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec); + return key; + } + + /** + * 获取ras私匙 + * @param privateKeyStr 私匙加密字符串 + * @return + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + */ + public static RSAPrivateKey getPrivateKey(String privateKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException { + + KeyFactory keyFactory = KeyFactory.getInstance(RSA); + PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64URLSafe(privateKeyStr)); + RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec); + return privateKey; + } + + /** + * 公匙加密 + * @param data 字符串 + * @param publicKey + * @return + */ + public static String publicEncrypt(String data, RSAPublicKey publicKey){ + + try { + Cipher cipher = Cipher.getInstance(RSA); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + +// byte[] bytes = cipher.doFinal(data.getBytes()); +// return Base64.encodeBase64URLSafeString(bytes); + return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength())); + }catch (Exception e){ + throw new RuntimeException(); + } + } + + public static String privateDecryption(String data, RSAPrivateKey privateKey){ + try { + Cipher cipher = Cipher.getInstance(RSA); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + +// byte[] bytes = cipher.doFinal(Base64.decodeBase64URLSafe(data)); +// return new String(bytes); + return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64URLSafe(data), privateKey.getModulus().bitLength()), CHARSET); + } catch (Exception e) { + throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e); + } + } + + //rsa切割解码 , ENCRYPT_MODE,加密数据 ,DECRYPT_MODE,解密数据 + private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) { + int maxBlock = 0; //最大块 + if (opmode == Cipher.DECRYPT_MODE) { + maxBlock = keySize / 8; + } else { + maxBlock = keySize / 8 - 11; + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + int offSet = 0; + byte[] buff; + int i = 0; + try { + while (datas.length > offSet) { + if (datas.length - offSet > maxBlock) { + //可以调用以下的doFinal()方法完成加密或解密数据: + buff = cipher.doFinal(datas, offSet, maxBlock); + } else { + buff = cipher.doFinal(datas, offSet, datas.length - offSet); + } + out.write(buff, 0, buff.length); + i++; + offSet = i * maxBlock; + } + } catch (Exception e) { + throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e); + } + byte[] resultDatas = out.toByteArray(); + IOUtils.closeQuietly(out); + return resultDatas; + } + + public static void main(String[] args) { + + Map encryptKey = createEncryptKey(); + String publicKey = encryptKey.get("publicKey"); + String privateKey = encryptKey.get("privateKey"); + + System.out.println("公匙加密串:" + publicKey); + System.out.println("私匙加密串:" + privateKey); + +// String data = "哈哈哈哈哈哈哈"; +// //加密 +// try { +// String s = publicEncrypt(data, getPublicKey(publicKey)); +// System.out.println("加密后密文:" + s); +// +// String s1 = privateDecryption(s, getPrivateKey(privateKey)); +// System.out.println("解密后明文:" + s1); +// +// }catch (Exception e){ +// throw new IllegalArgumentException(); +// } + + + } + + + +} diff --git a/src/main/java/cn/xf/basedemo/config/GlobalConfig.java b/src/main/java/cn/xf/basedemo/config/GlobalConfig.java new file mode 100644 index 0000000..d2bce8b --- /dev/null +++ b/src/main/java/cn/xf/basedemo/config/GlobalConfig.java @@ -0,0 +1,28 @@ +package cn.xf.basedemo.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @program: xf-boot-base + * @ClassName GlobalConfig + * @description: + * @author: xiongfeng + * @create: 2022-06-20 17:05 + **/ +@Data +@Component +@ConfigurationProperties(prefix = "global") +public class GlobalConfig { + + /** + * rsa 公匙 + */ + private String rsaPublicKey; + + /** + * rsa 私匙 + */ + private String rsaPrivateKey; +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index fc79205..c5e8888 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -19,6 +19,11 @@ spring: username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver + + +global: + rsaPublicKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4iSekTzDIfhE65qaThuySiDT0hWmmaB482ZMkJdwHH66SjJh_No_z8ZeJj774CrW0dtDfvPPpyS0-L-Gjs_V2FZea7hOfUrCZf0_GKjfovC_Ch_FqbXdP3nu5w4RePjhhIvqN99HWhb9tHi6W6Mupw5Fi5i4oSgtIxGVivDC2cwIDAQAB + rsaPrivateKey: MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALiJJ6RPMMh-ETrmppOG7JKINPSFaaZoHjzZkyQl3AcfrpKMmH82j_Pxl4mPvvgKtbR20N-88-nJLT4v4aOz9XYVl5ruE59SsJl_T8YqN-i8L8KH8Wptd0_ee7nDhF4-OGEi-o330daFv20eLpboy6nDkWLmLihKC0jEZWK8MLZzAgMBAAECgYAEhO9gmcPjFRtM6vsnX8WJbSaG2oGU3rXm3Zk56Gd0ETWQRzsw2mA6JC-G4etWXcTHb6V75T-_-PpPrJKFFNItEH-WFRS36xneomycxRG1YTfK1SsGLGF0BV3bLVZx8cQz7VsBY4vqbRCSKtcOZBJpnxI6iHAv07i8w34F6qjfsQJBAORnKUuJQ_GsHHBPT1VhMYjXVepAfTrWtCzRQ648KavbHLAGaRIhX10uj-hAhZLafDqQF8Y7T7GHTlasRL9ubWsCQQDO1R3KScJJSR3KDsnSsF0YCw7V28cr_OVAwiPoro90Me6MUz9yKV88gQlTuJkNFMuu_YdPXYKjlzNVg0zFmtUZAkEAoe9mPtDeZD0TmKkSZUVYul1543C_mPTan5_qrWCoZtkd2MtiuWEB3O4DR7ZfPcQ8KcU5pektUn_NEfRndZYUawJBAJfydOoxeawBLQNODfLcYefR59owlYe5SGpktaCw7O596DPqzId_4Vk_qqx4xueXSXOLCabCmcC4yZue0_2vm7ECQQDLrzXL-BpSqxbvtE0gNKcgaSkEUSOh1QmQFPCHERsOBxcflM6ej71STKglB21JD9m6tM2RySgbtUx4TfOuJTek ##redis #redis: # dynamic: diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d3de60c..1e87bf8 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -27,30 +27,31 @@ mybatis-plus: configuration: map-underscore-to-camel-case: false auto-mapping-behavior: full - #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #??SQL???? + #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启SQL语句打印 mapper-locations: classpath*:mapper/**/*Mapper.xml global-config: - # ?????? + # 逻辑删除配置 db-config: update-strategy: IGNORED - # ??? + # 删除前 logic-not-delete-value: 1 - # ??? + # 删除后 logic-delete-value: 0 knife4j: enable: true - production: false # ?????????true + production: false # 生产环境配置需设为true basic: - enable: false # ??Swagger?Basic????,???false - username: lianlian # Basic????? - password: lianlian123 # Basic???? + enable: false # 开启Swagger的Basic认证功能,默认是false + username: lianlian # Basic认证用户名 + password: lianlian123 # Basic认证密码 swagger: title: springboot基础框架 description: springboot基础框架 version: 1.0.0 - base-package: cn.xf.springbootbasedemo.controller + base-package: cn.xf.basedemo.controller +# 参考文章 https://zhuanlan.zhihu.com/p/145359625 management: endpoints: web: