资讯动态

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

发布时间:2026/8/8 10:24:17 来源:尧图企业网站定制
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 配置加密解密。工具类方式无需启动 Spring 容器静态调用即可使用自带 main 方法本地直接运行生成密文、解密测试支持单层 / 多层配置读取解析自动识别 ENC(加密串) 格式无感自动解密无侵入、轻量、可直接集成到现有项目。一、核心依赖项目依赖 Hutool 国密工具包 BouncyCastle 加密库!-- Hutool 国密加密SM4 --dependencygroupIdcn.hutool/groupIdartifactIdhutool-crypto/artifactIdversion5.8.20/version/dependency!-- BouncyCastle 密码学提供方 --dependencygroupIdorg.bouncycastle/groupIdartifactIdbcprov-jdk15on/artifactIdversion1.70/version/dependency二、YML 配置文件application.yml密钥规则SM4 密钥必须是 16 位字符数字 / 字母均可生产环境严禁硬编码在配置文件建议放到 Nacos / 密钥管理系统。加密格式固定ENC(SM4 加密后的密文)#国密SM4配置sm4:key:1234567890123456# 必须16位测试使用生产环境请放配置中心 #测试加密配置## 单层配置 testPassword:ENC(1bb11e4cf9eebd2538d53ebcaacb9cfe)## 多层配置 test:password:ENC(1bb11e4cf9eebd2538d53ebcaacb9cfe)三、国密 SM4 加密解密工具类Sm4Utilsimportcn.hutool.crypto.SmUtil;importcn.hutool.crypto.symmetric.SM4;/** * 国密 SM4 对称加密工具类 * 提供明文加密、密文解密 (本地可直接运行生成配置文件密文) * */publicclassSm4Utils{/** * 从配置文件读取 SM4 密钥16位 * 生产环境密钥不要硬编码建议从配置中心/密钥系统获取 */privatestaticfinalStringSM4_KEYApplicationConfigUtils.getProperty(sm4.key);/** * 初始化 SM4 加密对象全局单例避免重复创建 */privatestaticfinalSM4SM4_INSTANCESmUtil.sm4(SM4_KEY.getBytes());/** * SM4 加密明文 → 16进制密文 * param plainText 明文字符串 * return 可直接放入 ENC() 的密文 */publicstaticStringencrypt(StringplainText){if(plainTextnull||plainText.isEmpty()){thrownewIllegalArgumentException(加密明文不能为空);}returnSM4_INSTANCE.encryptHex(plainText);}/** * SM4 解密16进制密文 → 明文 * param cipherText 去除 ENC() 后的密文 * return 原始明文 */publicstaticStringdecrypt(StringcipherText){if(cipherTextnull||cipherText.isEmpty()){thrownewIllegalArgumentException(解密密文不能为空);}returnSM4_INSTANCE.decryptStr(cipherText);}publicstaticvoidmain(String[]args){// 待加密的明文如数据库密码、Redis密码StringoriginalData123456;System.out.println( SM4 加解密测试 );System.out.println(加密前明文originalData);// 加密结果直接复制到配置文件 ENC() 中StringencryptDataSm4Utils.encrypt(originalData);System.out.println(加密后密文encryptData);// 解密验证StringdecryptDataSm4Utils.decrypt(encryptData);System.out.println(解密后明文decryptData);}}四、配置文件读取解密工具类ApplicationConfigUtils无需启动 Spring可静态直接调用自动识别 ENC(xxx) 并解密支持单层 / 多层配置。/** * SpringBoot 配置文件读取工具类 * 无需启动Spring容器读取 application.yml 并自动解密 ENC(xxx) * 支持单层、多层级配置读取 国密 SM4 自动解密 * */publicclassApplicationConfigUtils{/** YAML 解析器 */privatestaticfinalYamlYAMLnewYaml();/** 配置文件缓存 Map */privatestaticfinalMapString,ObjectYML_CONFIG_MAP;/** 加密内容标识前缀、后缀 */privatestaticfinalStringENCRYPT_PREFIXENC(;privatestaticfinalStringENCRYPT_SUFFIX);// 静态代码块项目启动时一次性加载配置文件到内存static{try{// 读取 resources 下的 application.ymlResourceresourcenewClassPathResource(application.yml);if(!resource.exists()){thrownewRuntimeException(未找到配置文件application.yml请检查路径);}try(InputStreaminputStreamresource.getInputStream()){YML_CONFIG_MAPYAML.load(inputStream);}if(YML_CONFIG_MAPnull||YML_CONFIG_MAP.isEmpty()){thrownewRuntimeException(application.yml 配置文件内容为空);}}catch(Exceptione){thrownewRuntimeException(【配置加载失败】读取 application.yml 异常,e);}}/** * 读取配置自动解密 ENC 格式 * param key 配置项如test.password、testPassword * return 解密后的真实值 */publicstaticStringgetProperty(Stringkey){if(keynull||key.isBlank()){thrownewIllegalArgumentException(配置项 key 不能为空);}String[]keyskey.split(\\.);ObjectvaluegetNestedValue(YML_CONFIG_MAP,keys,0);// 自动识别并解密returnautoDecrypt(value);}/** * 读取配置带默认值避免报错 */publicstaticStringgetProperty(Stringkey,StringdefaultValue){try{returngetProperty(key);}catch(Exceptione){returndefaultValue;}}/** * 递归获取多层配置值如 a.b.c */privatestaticObjectgetNestedValue(MapString,ObjectcurrentMap,String[]keys,intindex){if(indexkeys.length-1){returncurrentMap.get(keys[index]);}ObjectnextNodecurrentMap.get(keys[index]);if(!(nextNodeinstanceofMap)){thrownewRuntimeException(配置节点不存在keys[index]);}returngetNestedValue((MapString,Object)nextNode,keys,index1);}/** * 自动解密判断是否为 ENC(xxx) 格式是则解密否则直接返回 */privatestaticStringautoDecrypt(Objectvalue){if(valuenull){returnnull;}StringstrValueString.valueOf(value);// 匹配加密格式自动解密if(strValue.startsWith(ENCRYPT_PREFIX)strValue.endsWith(ENCRYPT_SUFFIX)){StringcipherTextstrValue.substring(ENCRYPT_PREFIX.length(),strValue.length()-ENCRYPT_SUFFIX.length());returnSm4Utils.decrypt(cipherText);}// 非加密格式直接返回returnstrValue;}publicstaticvoidmain(String[]args){System.out.println( 配置文件解密测试 );// 单层配置Stringpwd1getProperty(testPassword);System.out.println(单层配置 testPassword 解密结果pwd1);// 多层配置Stringpwd2getProperty(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);// 获取配置信息Stringpwd2ApplicationConfigUtils.getProperty(test.password);System.out.println(pwd2: pwd2);}}七、问题解决运行ApplicationConfigUtils中main方法报错找不到配置文件原因项目是多模块项目项目有多个子模块apiservicemapperpojocommonApplicationConfigUtils工具类位置放到common子模块中和application.yml配置文件不在同一模块。报错Unchecked cast: ‘java.lang.Object’ to ‘java.util.Map’原因配置解析时类型转换不规范。解决方案ApplicationConfigUtils工具类中getSafeMap方法中将 Object 安全强转为 MapString, Object消除 Unchecked cast 警告。报错NullPointerException空指针原因1application.yml文件不存在或路径错误 。解决方案检查文件是否在resources目录下文件名是否正确application.yml。原因2SM4密钥未配置或配置错误。解决方案检查yml中sm4.key是否配置是否为16位。八、总结本文实现了一套轻量、无侵入、合规的 SpringBoot 国密 SM4 配置加密方案纯工具类实现不依赖 Spring 容器本地可直接测试自动识别 ENC(xxx) 格式业务代码无感解密支持单层 / 多层 YML 配置满足企业级项目需求完全符合等保、密评、国产化要求可直接用于生产环境。集成后彻底解决配置文件敏感信息明文泄露风险一步到位满足安全合规要求。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价