2config RSA 加密 · SpringCloud微服务实战 · 看云

导航


本节代码地址


上节我们介绍了AES 对接加密的方式,通过在Spring Cloud Config 中,通过直接在密文前面加上{cipher}来对密文进行标注,同时应用在启动的时候回按照规则进行解密,通过这种方式可以对敏感信息进行保护。

本节主要介绍RSA 非对称加密的方式,RSA 秘钥的生成相对复杂一点,但是安全性也提高了很多

1. 生成密钥对

首先我们需要通过keytool 工具类生成密钥对,keytool 是 JDK 中的一个密钥和证书的管理工具,在JDK 1.4 以后的版本都有这个工具,位置在%JAVA_HOME%\bin\keytool.exe
执行一下命令,生成密钥对

keytool -genkeypair -alias config-server-key -keyalg RSA -dname "CN=Config Server,OU=FWCLOUD,O=Company,L=ShangHai,S=ShangHai,C=CN" -keypass 123456 -keystore D:/JavaTools/config-server/config-server.keystore -storepass 123465

-genkeypair 参数即产生一对public key和private key。
-alias 指定key的别名,用于区分同一keystore中不同的key。
-keyalg 指定生成key的算法,这里使用默认的RSA
-dname 指定common name,即CN,用以验证key的身份。其中各项皆为自定义参数,OU为单位名称,O为组织名称,L为城市,S为省份/州,C为国家
-keypass 为key的密码
-keystore 为keystore的文件名
-storepass 访问keystore的密码

将生成的config-server.keystore 复制到项目路径下面
fd172a0907c72078b35c13918b525e6f_MD5.webp

2. 新建演示模块(已建的可以跳过)

新建模块fw-cloud-config-native-client-jce用来测试加密解密的环境演示
3a5a4ce9574bd588e57ecbff0a2399d9_MD5.webp

2.1 maven 配置

引入Config 客户端需要的包和Eureka 的包,因为后面我们基础Eureka 和 Config Server 通信获取配置文件的内容。并且引入了fw-cloud-base-dao(用户表的基本操作),减少重复代码的开发

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.yisu.cloud</groupId>
        <artifactId>fw-cloud-base-dao</artifactId>
        <version>${version}</version>
    </dependency>
    <dependency>
        <groupId>com.yisu.cloud</groupId>
        <artifactId>fw-cloud-common</artifactId>
        <version>${version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

2.2 控制层代码

通过加密后的密码我们查询用户数据,可以验证Spring Cloud Config 是否正确解密。

@RestController
public class SysUserController {

    @Autowired
    private SysUserService sysUserService;



    
    @PostMapping("/getUsers")
    public FwResult getUsers() {
        return FwResult.ok(sysUserService.list());
    }
}

2.3 启动类配置

这里只需要配置@SpringBootApplication注解和服务发现所需要的@EnableDiscoveryClient注解即可

@EnableDiscoveryClient
@SpringBootApplication
public class FwConfigNativeClientJceApplication {
    public static void main(String[] args) {
        SpringApplication.run(FwConfigNativeClientJceApplication.class, args);
    }
}

2.4 应用配置

这里主要配置了端口、应用名称、Config Server 的 服务名

server:
  port: 8780
spring:
  application:
    name: fw-config-jce-rsa
  cloud:
    config: #自己指定的和服务发现的2选1
#      uri: http://localhost:8778/  自己指定的
      profile: dev
      label: master
      discovery: #基于服务发现的
        enabled: true
        service-id: fw-config-server
management:
  endpoints:
    web:
      exposure:
        include: refresh,health,info

搞了这么久也没发现使用AES 加密啊,那是因为配置都在Config Server 那里,下面我们要改造Config Server 了

3. Config Server 端的改造

改造内容

  1. application.yml 修改为bootstrap.yml 主要是为了配置的优先加载
  2. 添加AES 的配置,因为AES 需要设置加密的key
server:
  port: 8778
#config server native模式
spring:
  application:
    name: fw-config-server
  profiles:
    active: native
  cloud:
    config:
      server:
        native:
          searchLocations: classpath:/native #  绝对路径 如 file:D:/workspace/fw-repo 相对路径:如classpath:/native
#        overrides:
#          version: 覆盖优先1.0
#      allow-override: true

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

encrypt:
  # rsa
  key-store:
    location: classpath:/config-server.keystore
    password: 123456
    alias: config-server-key
    secret: 123456

3.1 检测加密是否可用

启动Config Server ,使用Postman或浏览器测试localhost:8778/encrypt/status
337a4244d45610d299d4ed1c1b1cbdd5_MD5.png

如果返回的结果是“OK” ,说明加密可以用了

3.2 设置一个加密值

通过Postman Post调用localhost:8778/encrypt
ef5c08e5a11f05c58a8446b531b766e6_MD5.png

解密测试,通过Postman Post 调用 localhost:8778/decrypt
e9d00d0ceddd2a8b95885a3c64e749b6_MD5.png

3.3 设置fw-config-jce-rsa.properties

配置文件我这里使用另一种方式properties,这里使用properties、yml 都没问题,我们这里的spring.datasource.password密码是哪里来的呢?就是3.2 中加密的值

spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.url=jdbc:mysql://${dbIp}:3306/fw_jwt?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false
spring.datasource.username=root
spring.datasource.password={cipher}AQCFERtbi2UutdLb6whrvdFqxBCJHuU+HUHeJJ0H+socLv5m7JHtKBapJvwavtp4cbERuo0Zr5ioR22g0FHsinqJtLP4ZaVQU8M+WggMXdncWudVy3QmrcoQ/ochSxjrurojHcmRiDqfjtfXZxehSt1qB2tU9Y5zgwQ4tGptwiz/qYx8hKeBQG0zliamvWNyhXn8MfFf9nHlLtoXkrWhf+falTPY67eSjgRbbMwJQcfWC33c+IxZG+4/gflIlhw+SuJ0g8ykRpmbex0Tvc3exbZudnu1RRY7q4ViBuju26JFatsrQGYB4SkkdmuaQbjWcPJZp0YbMuwG6FAKAbqeeSCLDf/E6+YcjrfCP0UNQ97legIn3krequq6BwtbqZxwrFc=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.hikari.connection-timeout=20000
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.max-lifetime=1200000
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=12
spring.datasource.hikari.idle-timeout=300000
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
logging.level.com.yisu=debug
version=eureka-jce-2.0

3.4 创建数据库和表

在mysql执行以下语句

CREATE DATABASE fw_jwt;
USE fw_jwt;
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
  `update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
  `create_user` varchar(100) NOT NULL COMMENT '创建人编码',
  `update_user` varchar(100) NOT NULL COMMENT '修改人编码',
  `delete_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标记(1 删除 0未删除)',
  `pos_code` varchar(50) DEFAULT NULL COMMENT '职位编码',
  `disable_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '启用标记(1 禁用 0启用)',
  `avatar` varchar(100) DEFAULT NULL COMMENT '头像地址',
  `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
  `password` varchar(100) DEFAULT NULL COMMENT '密码',
  `user_name` varchar(50) DEFAULT NULL COMMENT '用户名',
  `real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名',
  `dept_code` varchar(50) DEFAULT NULL COMMENT '部门编码',
  `user_phone` varchar(15) DEFAULT NULL COMMENT '手机号',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `idx_email` (`email`) USING BTREE COMMENT '邮箱索引',
  UNIQUE KEY `idx_user_name` (`user_name`) USING BTREE COMMENT '用户名索引',
  KEY `idx_dept_code` (`dept_code`) USING BTREE COMMENT '部门编码索引',
  KEY `idx_position_code` (`pos_code`) USING BTREE COMMENT '职位编码索引'
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='系统用户表';


4.0 启动测试

需要先启动fw-register-eurekafw-config-server ,然后启动fw-config-jce-rsa 客户端
Postman 输入localhost:8780/getUsers测试从数据库获取用户信息
4841f069b301a7b2bb995ceb809f4fbc_MD5.png