当前位置: 首页 > news >正文

手机网站模块关键词推广公司

手机网站模块,关键词推广公司,做图片推广的网站,wordpress本地怎么迁移到服务器在Spring Boot项目中, 可以结合Jasypt 快速实现对配置文件中的部分属性进行加密。 完整的介绍参照: Spring Boot Jasypt 实现application.yml 属性加密的快速示例 但是作为一个技术强迫症,总是想着从底层开始实现属性的加解密,…

在Spring Boot项目中, 可以结合Jasypt 快速实现对配置文件中的部分属性进行加密。 完整的介绍参照:

Spring Boot + Jasypt 实现application.yml 属性加密的快速示例

但是作为一个技术强迫症,总是想着从底层开始实现属性的加解密,以解答这背后机制的疑惑。

本篇在不使用Jasypt 的状况下,实现配置文件的加密,并且应用启动的时候自动解密加密属性以供系统使用。

1. 定义一个加解密的工具类

/*** Copyright (C)  Oscar Chen(XM):* * Date: 2025-01-07* Author: XM*/package com.osxm.sb.encyproperties.util;import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;public class SecurityUtil {private static final String AES_GCM_NOPADDING = "AES/GCM/NoPadding";private static final int GCM_TAG_LENGTH = 128;private static final int GCM_IV_LENGTH = 12;public static SecretKey generateKeyByPassword(String password) throws Exception {// 使用SHA-256哈希函数MessageDigest sha = MessageDigest.getInstance("SHA-256");byte[] keyBytes = sha.digest(password.getBytes("UTF-8"));// AES-256需要一个长度为256位的密钥,所以取哈希的前32字节keyBytes = Arrays.copyOf(keyBytes, 32);// 创建密钥SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");return secretKey;}public static String encrypt(String data, String password) throws Exception {SecretKey key = generateKeyByPassword(password);return encrypt(data, key);}public static String encrypt(String data, SecretKey key) throws Exception {Cipher cipher = Cipher.getInstance(AES_GCM_NOPADDING);byte[] iv = new byte[GCM_IV_LENGTH];SecureRandom.getInstanceStrong().nextBytes(iv);GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);cipher.init(Cipher.ENCRYPT_MODE, key, gcmParameterSpec);byte[] encryptedData = cipher.doFinal(data.getBytes());byte[] encryptedDataWithIv = new byte[iv.length + encryptedData.length];System.arraycopy(iv, 0, encryptedDataWithIv, 0, iv.length);System.arraycopy(encryptedData, 0, encryptedDataWithIv, iv.length, encryptedData.length);return Base64.getEncoder().encodeToString(encryptedDataWithIv);}public static String decrypt(String data, String password) throws Exception {SecretKey key = generateKeyByPassword(password);return decrypt(data, key);}public static String decrypt(String encryptedDataWithIv, SecretKey key) throws Exception {byte[] decodedData = Base64.getDecoder().decode(encryptedDataWithIv);Cipher cipher = Cipher.getInstance(AES_GCM_NOPADDING);byte[] iv = new byte[GCM_IV_LENGTH];System.arraycopy(decodedData, 0, iv, 0, iv.length);GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);cipher.init(Cipher.DECRYPT_MODE, key, gcmParameterSpec);byte[] encryptedData = new byte[decodedData.length - iv.length];System.arraycopy(decodedData, iv.length, encryptedData, 0, encryptedData.length);byte[] decryptedData = cipher.doFinal(encryptedData);return new String(decryptedData);}
}

2. 定义一个继承EnumerablePropertySource的类: EncryptedPropertySource

EncryptedPropertySource用于将数据库密码、API密钥等敏感配置信息以加密的形式存储。这样,即使配置文件(如.properties文件或环境变量)被未经授权的人员访问,他们也无法直接获取到敏感的明文信息,因为信息已经被加密处理。

/*** Copyright (C)  Oscar Chen(XM):* * Date: 2025-01-07* Author: XM*/
package com.osxm.sb.encyproperties.config;import java.util.HashMap;
import java.util.Map;import org.springframework.core.env.EnumerablePropertySource;import com.osxm.sb.encyproperties.util.SecurityUtil;public class EncryptedPropertySource extends EnumerablePropertySource<Map<String, Object>> {private final Map<String, Object> properties = new HashMap<>();public EncryptedPropertySource(String name, Map<String, Object> source) {super(name, source);source.forEach((key, value) -> {if (value != null) {try {properties.put(key, decrypt(value.toString()));} catch (Exception e) {properties.put(key, value);}}});}@Overridepublic String[] getPropertyNames() {return properties.keySet().toArray(new String[0]);}@Overridepublic Object getProperty(String name) {return properties.get(name);}private String decrypt(String encryptedValue) throws Exception {// 在这里实现你的解密逻辑// 例如,假设加密值是 "ENC(encryptedPassword)" 格式if (encryptedValue.startsWith("ENC(") && encryptedValue.endsWith(")")) {String encryptedPassword = encryptedValue.substring(4, encryptedValue.length() - 1);// 这里使用简单的Base64解码作为示例,你可以使用更复杂的解密算法return SecurityUtil.decrypt(encryptedPassword, "oscar");}return encryptedValue;}
}

3. 在启动类中添加初始化动作

在 Spring Boot 中,addInitializers方法通常用于向ConfigurableApplicationContext添加自定义的ApplicationContextInitializerApplicationContextInitializer是一个接口,允许你在ApplicationContext刷新之前进行一些初始化工作。这在一些高级配置和启动时设置环境变量或属性时非常有用。

在Spring Boot中,environment对象通常指的是Environment接口的一个实例,它提供了访问应用程序属性源(PropertySource)的方法。PropertySource是一个抽象,它定义了如何访问一组属性(键值对)。

environment.getPropertySources().addFirst(...)这行代码的作用是将一个新的PropertySource实例添加到当前Environment的属性源列表的最前面。这意味着当Spring Boot查找某个属性时,它会首先在这个新添加的PropertySource中查找,如果找不到,才会继续在其他属性源中查找。

这种方法通常用于覆盖或添加额外的配置属性,特别是在需要确保某些属性具有最高优先级时。例如,你可能希望在应用程序启动时从外部源(如环境变量、命令行参数或加密的配置服务)加载配置,并确保这些配置覆盖任何默认或先前加载的配置。
这里的完整启动类代码如下:

@SpringBootApplication
public class EncypropertiesApplication {public static void main(String[] args) {SpringApplication application = new SpringApplication(EncypropertiesApplication.class);application.addInitializers(new ApplicationContextInitializer<ConfigurableApplicationContext>() {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {ConfigurableEnvironment environment = applicationContext.getEnvironment();try (InputStream input = new ClassPathResource("application.yml").getInputStream()) {Yaml yaml = new Yaml();Map<String, Object> yamlProperties = yaml.load(input);Map<String, Object> flattenedProperties = new HashMap<>();flattenMap(yamlProperties, flattenedProperties, null);EncryptedPropertySource encryptedPropertySource = new EncryptedPropertySource("encryptedProperties",flattenedProperties);environment.getPropertySources().addFirst(encryptedPropertySource);} catch (IOException e) {e.printStackTrace();}}private void flattenMap(Map<String, Object> source, Map<String, Object> target, String path) {source.forEach((key, value) -> {String fullPath = (path == null ? key : path + "." + key);if (value instanceof Map) {flattenMap((Map<String, Object>) value, target, fullPath);} else {target.put(fullPath, value);}});}});application.run(args);}}

4. 验证

以上配置是否生效,可以通过Debug 模式调试加密字符串是否正常被解密。
在这里插入图片描述

完整的测试是在 application.yml 配置数据库的密码,整合起来验证是否能正确连接DB。

spring:application:name: encypropertiesdatasource:url: jdbc:mysql://localhost/osxmdbusername: rootpassword: ENC(gfsTDJv1lgAfp4q0XcrhMp3+ijj8T2Go/UPdYbPJPXa6PQ==)driver-class-name: com.mysql.cj.jdbc.Driver

本篇完整示例

  • https://github.com/osxm/springbootency/tree/main/encyproperties


http://www.15wanjia.com/news/179878.html

相关文章:

  • 如何搜索网站的内容项目外包的成本构成
  • 做查询快递单号的网站多少钱公司网站要使用我个人的信息备案
  • 建网站 免费青岛房产
  • 做网站和游戏是如何赚钱网站icp备案网址
  • 建设好网站seo公司 上海
  • 福田网站建设效果渭南汽车网站制作
  • 北京网站策划联系电话深圳服装网站建设
  • 云南公司网站开发睢县做网站哪家好
  • 用动易做的诗歌协会网站深圳品牌馆设计公司
  • 课题组网站建设12306网站建设投标书
  • 商家网站建设模板个人做网站赚钱么
  • 成都企业网站建设费用广东网站设计费用
  • 网站开发最快的语言百度网站地图怎么做
  • 专业做网文的网站好洛可可设计公司估值
  • 做外贸必须有公司网站么帮别人做数学题赚钱的网站
  • 网站设计就业压力网站建设费用明细报告
  • o2o网站市场营销策划方案模板
  • 响应式网站制作公司宜黄住房和城乡建设部网站
  • 做网站平面模板是啥意思定制商城网站的费用
  • 怎么用dw软件做网站设计网站公司的口号
  • 专题定制网站建设农业特色网站建设
  • win7 iis创建网站百度发布平台官网
  • 网站前端怎么做方法互联网协会是干嘛的
  • 宁波网站制作与推广价格以服务营销出名的企业
  • 银川网站建设公司排名html网页设计网站
  • 个人网站开发如何赚钱吗专业ppt代做
  • 努力把网站建设成为wordpress固定链接标签加上页面
  • 家电维修怎么自己做网站制作华为手机网站建设规划书
  • 鄂州网站设计制作大数据网站开发
  • 做慕墙上什么网站好找事做专门做眼镜的网站