SpringBoot 配置文件加密的步骤

SpringBoot 配置文件加密可以保护敏感的配置信息,比如数据库密码等,防止被恶意获取。下面是一些可能用到的步骤。

安装 JCE

JCE(Java Cryptography Extension)是Java加密扩展的缩写,如果你需要使用高强度加密算法,比如AES,那么需要下载安装对应的JCE版本。在Oracle官网下载后,将jar包解压到 $JAVA_HOME/jre/lib/security 目录下即可。

配置 application.properties

application.properties 中添加加密相关的配置,如下所示。

# 配置密钥,需要保证每个项目都不一样
encrypt.key=MY_ENCRYPT_KEY

# 配置需要加密的属性值
db.password=ENC(${cipher.db.password})

# 禁用 JMX
spring.jmx.enabled=false

其中,encrypt.key 是加密所使用的密钥,建议每个项目都使用不同的密钥;db.password 中的 ENC(${cipher.db.password}) 表示该值需要被加密,使用该格式添加需要加密的属性即可。

创建配置类

创建一个自定义的配置类,用于加密和解密。

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Arrays;

@Component
public class EncryptPropertyConfigurer {

    private static final String SHA_ALGORITHM = "SHA-256";
    private static final String ENCRYPTION_IV = "MY_ENCRYPTION_IV";

    @Value("${encrypt.key}")
    private String encryptKey;

    @Autowired
    private Environment environment;

    @PostConstruct
    public void init() {
        if (encryptKey == null || encryptKey.isEmpty()) {
            throw new IllegalArgumentException("encryptKey is empty");
        }
        if (ENCRYPTION_IV == null || ENCRYPTION_IV.isEmpty()) {
            throw new IllegalArgumentException("encryptionIV is empty");
        }
    }

    public String decrypt(String property) {
        if (!property.startsWith("ENC(") || !property.endsWith(")")) {
            throw new IllegalArgumentException("Invalid encrypted value: " + property);
        }
        property = property.substring(4, property.length() - 1);
        byte[] encryptedBytes = Base64.decodeBase64(property);
        try {
            SecretKeySpec secretKeySpec = getKeySpec();
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(ENCRYPTION_IV.getBytes("UTF-8")));
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            return new String(decryptedBytes, "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException("Error decrypting property", e);
        }
    }

    private SecretKeySpec getKeySpec() throws Exception {
        byte[] keyBytes = Arrays.copyOf(MessageDigest.getInstance(SHA_ALGORITHM).digest(encryptKey.getBytes("UTF-8")), 16);
        return new SecretKeySpec(keyBytes, "AES");
    }
}

该类使用 AES 算法进行加密和解密,encryptKey 为密钥,可以在 application.properties 设置,ENCRYPTION_IV 为初始向量。

示例1:加密单个属性

假设在 application.properties 文件中有以下属性:

db.password=root

可以将 db.password 进行加密,修改为:

db.password=ENC(ilOvI0UvbvRhIksj+GTw5g==)

其中,ilOvI0UvbvRhIksj+GTw5g== 是加密后的密码。

示例2:加密多个属性

示例1中只加密了一个属性,如果需要加密多个属性,可以使用下面的代码。

import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "cipher")
public class EncryptedPropertySource implements InitializingBean {

    private final EncryptPropertyConfigurer encryptPropertyConfigurer;

    public EncryptedPropertySource(EncryptPropertyConfigurer encryptPropertyConfigurer) {
        this.encryptPropertyConfigurer = encryptPropertyConfigurer;
    }

    private String dbPassword;
    private String secretKey;

    @Override
    public void afterPropertiesSet() {
        dbPassword = encryptPropertyConfigurer.decrypt(secretKey);
    }

    public String getDbPassword() {
        return dbPassword;
    }

    public void setDbPassword(String dbPassword) {
        this.dbPassword = dbPassword;
    }

    public String getSecretKey() {
        return secretKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }
}

该类使用 @ConfigurationProperties 注解读取加密后的属性,并使用 EncryptPropertyConfigurer 类解密。

以上是 SpringBoot 配置文件加密的一些步骤和示例,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot 配置文件加密的步骤 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • 关于c#:计算两个日期之间的差异(天数)?

    以下是关于在C#中计算两个日期之间的差异(天数)的完整攻略,包括基本知识和两个示例。 基本知识 在C#中,使用DateTime类型来表示日期和时间。要计算两个日期之间的差异(天数),可以使用DateTime类型的Subtract方法。Subtract方法返回TimeSpan类型的对象,表示两个日期之间的时间间隔。可以使用TimeSpan类型的Days属性来获…

    other 2023年5月7日
    00
  • VisualStudio怎么添加控件?

    下面是详细讲解“VisualStudio怎么添加控件?”的完整攻略: 1. 打开窗体设计器 在Visual Studio中打开工程文件,双击打开窗体文件,进入窗体设计器。你也可以通过在菜单中选择“View” -> “Solution Explorer”打开解决方案资源管理器,找到对应窗体文件并右键单击选择“View Designer”打开窗体设计器。 …

    other 2023年6月27日
    00
  • Arcgis Runtime for andriod 100 Simple marker symbol

    下面是“ArcGIS Runtime for Android 100 Simple Marker Symbol的完整攻略”,包括Simple Marker Symbol的基本概念、使用方法、示例说明等方面。 Simple Marker Symbol的基本概念 Simple Marker Symbol是ArcGIS Runtime for Android 10…

    other 2023年5月5日
    00
  • matplotlib:图片与子片 调整子图周围的间距

    Matplotlib: 调整子图周围的间距 Matplotlib是一个用于绘制数据可视化图表的Python库。在Matplotlib中,我们可以使用子图来在同一个图中绘制多个子图。在某些情况下,我们可能需要调整子图周围的间距。本攻略将介绍如何在Matplotlib中调整子图周围的间距。 步骤一:导Matplotlib库 在使用Matplotlib之前,我们导…

    other 2023年5月9日
    00
  • crypto.js下载

    Crypto.js下载 Crypto.js是一个JavaScript加密库,它提供了多种加密算法和工具,可以帮助我们在前端实现数据加密和解密。以下是Crypto.js下载的完整攻略。 步骤 以下是下载Crypto.js的步骤: 打开Crypto.js官网:https://cryptojs.gitbook.io/docs/ 点击“Download”按钮,下载C…

    other 2023年5月6日
    00
  • Office 32位与64位版本有什么区别?

    Office 32位与64位版本的区别 Microsoft Office是一套广泛使用的办公软件套件,提供了许多不同版本,其中包括32位和64位版本。这两个版本在以下几个方面有所不同: 1. 内存访问能力 32位版本:32位版本的Office在运行时可以访问最多4GB的内存。这是由于32位操作系统的限制,它们只能处理32位的内存地址。因此,无论计算机上有多少…

    other 2023年7月28日
    00
  • 基于React封装组件的实现步骤

    基于React封装组件的实现步骤可以分为以下几步: 1.确定组件的功能和需求:在封装组件之前,需要明确组件的功能和需求,以便于后续的设计和开发。 2.设计组件的API和属性:在确定组件的功能和需求后,需要设计组件的API和属性,例如组件的使用方式、接受的参数以及传递给子组件的属性等。 3.编写组件的代码:根据组件的设计和API,编写组件的代码,并设置初始状态…

    other 2023年6月25日
    00
  • Java编程子类能否重写父类的静态方法探索

    让我们来探索一下Java编程中子类是否能够重写父类的静态方法吧! 1. 静态方法的特点 首先,我们需要了解静态方法的一些特点。静态方法是一种属于类级别的方法,其作用就是提供单一的全局访问点。不同于普通方法,静态方法是无法被实例化对象所调用,只能通过类名来访问和使用。因此,静态方法的调用方式会简单和方便许多。 2. 子类重写父类静态方法 从以上了解中我们可以看…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部