spring和springboot中加密连接数据库的信息

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 前言:在实际开发中,一些关键的信息肯定是要加密的,否则就太不安全了。比如连接数据库的用户名和密码,一般就需要加密。接下来就看看spring项目和spring boot项目中分别是如何加密这些信息的。

前言:

在实际开发中,一些关键的信息肯定是要加密的,否则就太不安全了。比如连接数据库的用户名和密码,一般就需要加密。接下来就看看spring项目和spring boot项目中分别是如何加密这些信息的。

一、spring中加密连接数据库的信息:

spring项目中,我们一般把连接数据库的信息写在jdbc.properties中,然后在spring-dao.xml中读取配置信息。
未加密是这样写的:
jdbc.properties:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///test?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123
AI 代码解读

然后在spring-dao.xml中读取:

<context:property-placeholder location="classpath:jdbc.properties" />
AI 代码解读

要加密需要进行以下操作:
1、编写DES算法加密工具类:
DESUtil.java:

import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


/**
 * 用DES对称算法加密数据库连接的信息</br>
 * 所谓对称算法就是加密和解密使用相同的key
 * 
 * @author zhu
 *
 */
public class DESUtil {
    private static Key key;
    // 设置密钥key
    private static String KEY_STR = "myKey";
    private static String CHARSETNAME = "UTF-8";
    private static String ALGORITHM = "DES";

    static {
        try {
            // 生成des算法对象
            KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
            // 运用SHA1安全策略
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            // 设置密钥种子
            secureRandom.setSeed(KEY_STR.getBytes());
            // 初始化基于SHA1的算法对象
            generator.init(secureRandom);
            // 生成密钥对象
            key = generator.generateKey();
            generator = null;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    /**
     * 获取加密后的信息
     * 
     * @param str
     * @return
     */
    public static String getEncryptString(String str) {
        // 基于BASE64编码,接收byte[]并转换层String
        BASE64Encoder base64encoder = new BASE64Encoder();
        try {
            // utf-8编码
            byte[] bytes = str.getBytes(CHARSETNAME);
            // 获取加密对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 初始化密码信息
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // 加密
            byte[] doFinal = cipher.doFinal(bytes);
            // 返回
            return base64encoder.encode(doFinal);
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    /**
     * 获取解密之后的信息
     * 
     * @param str
     * @return
     */
    public static String getDecryptString(String str) {
        //基于BASE64编码,接收byte[]并转换成String
        BASE64Decoder base64decoder = new BASE64Decoder();
        try {
            //将字符串decode成byte[]
            byte[] bytes = base64decoder.decodeBuffer(str);
            //获取解密对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //初始化解密信息
            cipher.init(Cipher.DECRYPT_MODE, key);
            //解密
            byte[] doFinal = cipher.doFinal(bytes);
            //返回解密之后的信息
            return new String(doFinal,CHARSETNAME);
        }catch(Exception e) {
            throw new RuntimeException(e);
        }
    }
    
       /**
     * 测试
     * 
     * @param args
     */
    public static void main(String[] args) {
        // 加密root字符串
        System.out.println(getEncryptString("root"));
        // 加密123
        System.out.println(getEncryptString("123"));
        // 解密WnplV/ietfQ=
        System.out.println(getDecryptString("WnplV/ietfQ="));
    }
}
AI 代码解读

这个类就实现了DES算法加密字符串,把需要加密的字段传入getEncryptString方法即可加密。看运行效果:

img_5b7250b42b551fd95dd3022aa4dc6370.png
image.png

注意:
在编写这个类的时候,BASE64Encoder一直报错,找不到 sun.misc.BASE64Encoder包,没办法import这个包。
解决办法:
选中项目 ---> build path ---> libraries ---> jre system library ---> access rules
---> edit ---> add ---> accessble ---> ** ---> ok
img_323747561eb4f3cfb4b543d48d70a6f5.png
image.png

img_55633908a9627e932b50646b0c9cadf9.png
image.png

2、把jdbc.properties中的字段换成加密后的
jdbc.properties:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///test?useUnicode=true&characterEncoding=utf8
jdbc.username=WnplV/ietfQ=
jdbc.password=um461kxL7IU=
AI 代码解读

3、在spring读取配置时解密
以上两步完成了加密,但是这样spring读取时并不会自动解密这些经过加密的字段,所以还需要进行如下操作:
EncryptPropertyPlaceholderConfigurer.java:

import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

/**
 * 在spring-dao加载jdbc.properties时,将加密信息解密出来
 * 
 * @author zhu
 *
 */
public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
    // 需要加密的字段数组
    private String[] encryptPropNames = { "jdbc.username", "jdbc.password" };

    protected String convertProperty(String propertyName, String propertyValue) {
        if (isEncryptProp(propertyName)) {
            // 对加密的字段进行解密工作(调用DESUtil中的解密方法)
            String decryptValue = DESUtil.getDecryptString(propertyValue);
            return decryptValue;
        } else {
            return propertyValue;
        }
    }

    /**
     * 该属性是否已加密
     * 
     * @param propertyName
     * @return
     */
    private boolean isEncryptProp(String propertyName) {
        // 若等于需要加密的field,则进行加密
        for (String encryptpropertyName : encryptPropNames) {
            if (encryptpropertyName.equals(propertyName)) {
                return true;
            }
        }
        return false;
    }

}
AI 代码解读

这段代码就对jdbc.username和jdbc.password进行了解密。然后在spring-dao.xml中以如下方式读取jdbc.properties:
spring-dao.xml:

    <bean
        class="com.zhu.util.EncryptPropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
        <property name="fileEncoding" value="UTF-8" />
    </bean>
AI 代码解读

这里就把EncryptPropertyPlaceholderConfigurer配置成了bean,用这个类去读取jdbc.properties就可以解密了。

4、连接测试:
DESTest.java:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mysql.jdbc.Driver;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:spring/spring-dao.xml"})
public class DESTest {
    
    @Test
    public void testGetDataSource() {
        System.out.println(Driver.class);
    }

}
AI 代码解读

运行结果:


img_a61a1a8a5e4dacc1080b76efbcd3dd02.png
image.png

连接成功!

二、springboot项目中加密数据库连接信息:

springboot项目没有jdbc.properties,也没有spring-dao.xml,全都写在application.properties或application.yml中。需要加密的话执行如下操作即可:

1、引入jasypt的jar包:

        <dependency>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-spring-boot-starter</artifactId>
            <version>1.16</version>
        </dependency>
AI 代码解读

2、在application.properties中配置加密key:
这个key可以自己随便写,我写的是hellospringboot。

#配置数据源加密的密钥
jasypt.encryptor.password=hellospringboot
AI 代码解读

3、使用jasypt加密字段:

import org.jasypt.encryption.StringEncryptor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class test {
    
    //注入StringEncryptor
    @Autowired
    StringEncryptor encryptor;
    
    @Test
    public void encry() {
        //加密root
        String username = encryptor.encrypt("root");
        System.out.println(username);
        //加密123
        String password = encryptor.encrypt("123");
        System.out.println(password);
    }
}
AI 代码解读

运行结果:

img_9267e8efb5917301573819ad214ea207.png
image.png

这两个就是root和123加密后的结果。
注意:
这个测试类每运行一次输出的结果都是不一样的,比如第一次运行是上图结果,第二次运行加密结果又不一样了,这是正常现象。随便复制哪一次的运行结果到application.properties中都行。

4、在application.properties中配置连接数据库的信息:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql:///meilianMall?useUnicode=true&characterEncoding=utf8
spring.datasource.username=ENC(UltArcVy251RWehUvajQmg==)
spring.datasource.password=ENC(y23g0pb97XsBULm3ILNWTg==)
AI 代码解读

注意:
加密字段需要用ENC(密文)的形式,直接写spring.datasource.username=UltArcVy251RWehUvajQmg是无效的。

5、连接测试:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.mysql.jdbc.Driver;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class test {

    @Test
    public void testGetDataSource() {
        System.out.println(Driver.class);
    }
    
}
AI 代码解读
img_9c3a58770cbe04ba8420f4f386ac6c5a.png
image.png

可以看到也是连接成功的。

总结:

spring项目中加密数据库连接信息的方法稍微麻烦一点,要加密又要解密,而springboot采用的jasypt加密相当于解密工作它会自动完成,我们只需要在application.properties中配置密钥和加密后的信息即可。

以上内容属于个人笔记整理,如有错误,欢迎批评指正!

相关文章
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
13 2
使用 Spring Boot 执行数据库操作:全面指南
使用 Spring Boot 执行数据库操作:全面指南
219 1
Linux下ODBC与 南大通用GBase 8s数据库的无缝连接配置指南
本文详细介绍在Linux系统下配置GBase 8s数据库ODBC的过程,涵盖环境变量设置、ODBC配置文件编辑及连接测试等步骤。首先配置数据库环境变量如GBASEDBTDIR、PATH等,接着修改odbcinst.ini和odbc.ini文件,指定驱动路径、数据库名称等信息,最后通过catalog.c工具或isql命令验证ODBC连接是否成功。
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(上)
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(上)
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(下)
本文接续前文,深入讲解了在Windows环境下使用C#和ADO.NET操作南大通用GBase 8s数据库的方法。通过Visual Studio 2022创建项目,添加GBase 8s的DLL引用,并提供了详细的C#代码示例,涵盖数据库连接、表的创建与修改、数据的增删查改等操作,旨在帮助开发者提高数据库管理效率。
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
217 1
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
148 62
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
130 13
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等