news 2026/5/8 21:21:35

SpringBoot 国密 SM4 配置加密(工具类实现)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot 国密 SM4 配置加密(工具类实现)

SpringBoot 国密 SM4 配置加密(工具类实现)

    • 前言
    • 一、核心依赖
    • 二、YML 配置文件(application.yml)
    • 三、国密 SM4 加密解密工具类(Sm4Utils)
    • 四、配置文件读取解密工具类(ApplicationConfigUtils)
    • 五、运行测试(直接执行 main 方法)
      • 1. 生成密文(运行 Sm4Utils中main方法)
      • 2. 配置解密(运行 ApplicationConfigUtils工具类中main方法)
    • 六、业务代码调用
    • 七、问题解决
    • 八、总结

前言

在企业级 SpringBoot 项目中,配置文件(application.yml)往往存储着大量敏感信息(比如:数据库密码、Redis 密码、MQ 账号密码、第三方密钥等)。如果明文存储,一旦配置文件泄露,会直接导致核心服务被入侵,属于等保、密评、PIPL 合规高风险项。因此,配置文件敏感信息必须加密,且生产环境必须使用国密 SM4 算法,满足国产化、合规要求。

本文基于 Java8 + SpringBoot2.3.7,采用纯工具类方式实现国密 SM4 配置加密解密。工具类方式:

  1. 无需启动 Spring 容器,静态调用即可使用;
  2. 自带 main 方法,本地直接运行生成密文、解密测试;
  3. 支持单层 / 多层配置读取解析;
  4. 自动识别 ENC(加密串) 格式,无感自动解密;
  5. 无侵入、轻量、可直接集成到现有项目。

一、核心依赖

项目依赖 Hutool 国密工具包 + BouncyCastle 加密库:

<!-- Hutool 国密加密(SM4) --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-crypto</artifactId><version>5.8.20</version></dependency><!-- BouncyCastle 密码学提供方 --><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.70</version></dependency>

二、YML 配置文件(application.yml)

密钥规则:SM4 密钥必须是 16 位字符(数字 / 字母均可),生产环境严禁硬编码在配置文件,建议放到 Nacos / 密钥管理系统。加密格式固定:ENC(SM4 加密后的密文)

#======================国密SM4配置======================sm4:key:1234567890123456# 必须16位,测试使用,生产环境请放配置中心 #======================测试加密配置======================## 单层配置 testPassword:ENC(1bb11e4cf9eebd2538d53ebcaacb9cfe)## 多层配置 test:password:ENC(1bb11e4cf9eebd2538d53ebcaacb9cfe)

三、国密 SM4 加密解密工具类(Sm4Utils)

importcn.hutool.crypto.SmUtil;importcn.hutool.crypto.symmetric.SM4;/** * 国密 SM4 对称加密工具类 * 提供明文加密、密文解密 (本地可直接运行生成配置文件密文) * */publicclassSm4Utils{/** * 从配置文件读取 SM4 密钥(16位) * 生产环境:密钥不要硬编码,建议从配置中心/密钥系统获取 */privatestaticfinalStringSM4_KEY=ApplicationConfigUtils.getProperty("sm4.key");/** * 初始化 SM4 加密对象(全局单例,避免重复创建) */privatestaticfinalSM4SM4_INSTANCE=SmUtil.sm4(SM4_KEY.getBytes());/** * SM4 加密(明文 → 16进制密文) * @param plainText 明文字符串 * @return 可直接放入 ENC() 的密文 */publicstaticStringencrypt(StringplainText){if(plainText==null||plainText.isEmpty()){thrownewIllegalArgumentException("加密明文不能为空");}returnSM4_INSTANCE.encryptHex(plainText);}/** * SM4 解密(16进制密文 → 明文) * @param cipherText 去除 ENC() 后的密文 * @return 原始明文 */publicstaticStringdecrypt(StringcipherText){if(cipherText==null||cipherText.isEmpty()){thrownewIllegalArgumentException("解密密文不能为空");}returnSM4_INSTANCE.decryptStr(cipherText);}publicstaticvoidmain(String[]args){// 待加密的明文(如数据库密码、Redis密码)StringoriginalData="123456";System.out.println("=== SM4 加解密测试 ===");System.out.println("加密前明文:"+originalData);// 加密(结果直接复制到配置文件 ENC() 中)StringencryptData=Sm4Utils.encrypt(originalData);System.out.println("加密后密文:"+encryptData);// 解密验证StringdecryptData=Sm4Utils.decrypt(encryptData);System.out.println("解密后明文:"+decryptData);}}

四、配置文件读取解密工具类(ApplicationConfigUtils)

无需启动 Spring,可静态直接调用,自动识别 ENC(xxx) 并解密,支持单层 / 多层配置。

/** * SpringBoot 配置文件读取工具类 * 无需启动Spring容器,读取 application.yml 并自动解密 ENC(xxx) * 支持单层、多层级配置读取 + 国密 SM4 自动解密 * */publicclassApplicationConfigUtils{/** YAML 解析器 */privatestaticfinalYamlYAML=newYaml();/** 配置文件缓存 Map */privatestaticfinalMap<String,Object>YML_CONFIG_MAP;/** 加密内容标识前缀、后缀 */privatestaticfinalStringENCRYPT_PREFIX="ENC(";privatestaticfinalStringENCRYPT_SUFFIX=")";// 静态代码块:项目启动时一次性加载配置文件到内存static{try{// 读取 resources 下的 application.ymlResourceresource=newClassPathResource("application.yml");if(!resource.exists()){thrownewRuntimeException("未找到配置文件:application.yml,请检查路径");}try(InputStreaminputStream=resource.getInputStream()){YML_CONFIG_MAP=YAML.load(inputStream);}if(YML_CONFIG_MAP==null||YML_CONFIG_MAP.isEmpty()){thrownewRuntimeException("application.yml 配置文件内容为空");}}catch(Exceptione){thrownewRuntimeException("【配置加载失败】读取 application.yml 异常",e);}}/** * 读取配置(自动解密 ENC 格式) * @param key 配置项(如:test.password、testPassword) * @return 解密后的真实值 */publicstaticStringgetProperty(Stringkey){if(key==null||key.isBlank()){thrownewIllegalArgumentException("配置项 key 不能为空");}String[]keys=key.split("\\.");Objectvalue=getNestedValue(YML_CONFIG_MAP,keys,0);// 自动识别并解密returnautoDecrypt(value);}/** * 读取配置(带默认值,避免报错) */publicstaticStringgetProperty(Stringkey,StringdefaultValue){try{returngetProperty(key);}catch(Exceptione){returndefaultValue;}}/** * 递归获取多层配置值(如 a.b.c) */privatestaticObjectgetNestedValue(Map<String,Object>currentMap,String[]keys,intindex){if(index==keys.length-1){returncurrentMap.get(keys[index]);}ObjectnextNode=currentMap.get(keys[index]);if(!(nextNodeinstanceofMap)){thrownewRuntimeException("配置节点不存在:"+keys[index]);}returngetNestedValue((Map<String,Object>)nextNode,keys,index+1);}/** * 自动解密(判断是否为 ENC(xxx) 格式,是则解密,否则直接返回) */privatestaticStringautoDecrypt(Objectvalue){if(value==null){returnnull;}StringstrValue=String.valueOf(value);// 匹配加密格式,自动解密if(strValue.startsWith(ENCRYPT_PREFIX)&&strValue.endsWith(ENCRYPT_SUFFIX)){StringcipherText=strValue.substring(ENCRYPT_PREFIX.length(),strValue.length()-ENCRYPT_SUFFIX.length());returnSm4Utils.decrypt(cipherText);}// 非加密格式直接返回returnstrValue;}publicstaticvoidmain(String[]args){System.out.println("=== 配置文件解密测试 ===");// 单层配置Stringpwd1=getProperty("testPassword");System.out.println("单层配置 testPassword 解密结果:"+pwd1);// 多层配置Stringpwd2=getProperty("test.password");System.out.println("多层配置 test.password 解密结果:"+pwd2);}}

五、运行测试(直接执行 main 方法)

1. 生成密文(运行 Sm4Utils中main方法)

===SM4加解密测试===加密前明文:123456加密后密文:1bb11e4cf9eebd2538d53ebcaacb9cfe 解密后明文:123456

复制加密后的密文,直接填入 application.yml 的 ENC(xxx) 中。

2. 配置解密(运行 ApplicationConfigUtils工具类中main方法)

===配置文件解密测试===单层配置 testPassword 解密结果:123456多层配置 test.password 解密结果:123456

六、业务代码调用

无需注入、无需配置,可直接静态调用,即可获取解密后的真实值。如:

@SpringBootApplicationpublicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);// 获取配置信息Stringpwd2=ApplicationConfigUtils.getProperty("test.password");System.out.println("pwd2: "+pwd2);}}

七、问题解决

  1. 运行ApplicationConfigUtils中main方法报错,找不到配置文件
    原因:项目是多模块项目,项目有多个子模块(api,service,mapper,pojo,common),ApplicationConfigUtils工具类位置放到common子模块中,和application.yml配置文件不在同一模块。
  2. 报错:Unchecked cast: ‘java.lang.Object’ to ‘java.util.Map’
    原因:配置解析时类型转换不规范。解决方案:ApplicationConfigUtils工具类中getSafeMap方法中将 Object 安全强转为 Map<String, Object>,消除 Unchecked cast 警告。
  3. 报错:NullPointerException(空指针)
    原因1:application.yml文件不存在或路径错误 。解决方案:检查文件是否在resources目录下,文件名是否正确(application.yml)。
    原因2:SM4密钥未配置或配置错误。解决方案:检查yml中sm4.key是否配置,是否为16位。

八、总结

本文实现了一套轻量、无侵入、合规的 SpringBoot 国密 SM4 配置加密方案:

  1. 纯工具类实现,不依赖 Spring 容器,本地可直接测试;
  2. 自动识别 ENC(xxx) 格式,业务代码无感解密;
  3. 支持单层 / 多层 YML 配置,满足企业级项目需求;
  4. 完全符合等保、密评、国产化要求,可直接用于生产环境。

集成后彻底解决配置文件敏感信息明文泄露风险,一步到位满足安全合规要求。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 21:20:28

移动芯片行业生存法则:从四五千人团队规模看技术平台化竞争

1. 移动芯片行业的“人海战术”&#xff1a;一个被低估的生存门槛最近和几个还在半导体行业里摸爬滚打的老朋友聊天&#xff0c;话题又绕回了那个经典的问题&#xff1a;现在做手机芯片&#xff0c;到底得养多少人&#xff1f;这听起来像个管理学的课题&#xff0c;但实际干过的…

作者头像 李华
网站建设 2026/5/8 21:13:00

2026最权威的六大AI辅助论文网站解析与推荐

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 于当下的学术写作范围里头&#xff0c;AI工具已然变成了能够提高效率以及质量的关键辅助方式…

作者头像 李华
网站建设 2026/5/8 21:12:46

Pixel2Geo 厘米级定位,危化园区无感全域管控

Pixel2Geo 厘米级定位&#xff0c;危化园区无感全域管控 前言 危化园区高危场景复杂、管线密集、动火作业频繁、安全管控容错率极低&#xff0c;传统UWB、GPS、穿戴标签定位存在部署成本高、信号遮挡失效、跨相机断链、人员抵触管理等诸多局限&#xff0c;无法实现全域不间…

作者头像 李华
网站建设 2026/5/8 21:10:41

山东大学项目实训3——推荐算法引擎与地图 LBS 服务的深度集成

一、 进展概述 近两周&#xff0c;项目进入了最核心的业务逻辑开发期。我主要负责了“需求匹配与智能推荐智能体”的开发&#xff0c;并完成了高德地图 SDK 的深度集成。目前&#xff0c;系统已实现从结构化请求到具体服务点的精准映射&#xff0c;并能根据机场实时状态&#x…

作者头像 李华