Java 项目数据国密加密工具

张开发
2026/4/3 16:02:15 15 分钟阅读
Java 项目数据国密加密工具
1.加密工具源码packagecom.visy.common.util;importcn.hutool.core.util.HexUtil;importcn.hutool.core.util.StrUtil;importcn.hutool.crypto.SmUtil;importcn.hutool.crypto.asymmetric.KeyType;importcn.hutool.crypto.asymmetric.SM2;importcom.antherd.smcrypto.sm2.Sm2;importcom.antherd.smcrypto.sm4.Sm4;importcom.antherd.smcrypto.sm4.Sm4Options;importlombok.extern.slf4j.Slf4j;importjava.security.SecureRandom;/** * 加密工具类本框架目前使用 a hrefhttps://github.com/antherd/sm-cryptosm-crypto/a 项目中一些加解密方式 * 使用小伙伴需要过等保密评相关请在此处更改为自己的加密方法或加密机使用加密机同时需要替换公钥私钥在内部无法导出提供加密的方法 * 如果不涉及到加密机方面的内容请更改公私要为自己重新生成的生成方式请看集成的sm-crypto主页 * * author yubaoshan * date 2022/9/15 21:51 */Slf4jpublicclassCommonCryptogramUtil{privatestaticStringPUBLIC_KEY;//SM2公钥privatestaticStringPRIVATE_KEY;//SM2私钥privatestaticStringKEY;//SM4密钥privatestaticSM2sm2;//SM2对象/** * 由 CryptoProperties 在启动时调用完成静态字段初始化 */publicstaticvoidinit(StringpublicKey,StringprivateKey,Stringkey){if(StrUtil.isNotBlank(publicKey)StrUtil.isNotBlank(privateKey)){log.info(加密工具密钥-SM2密钥对已更新);PUBLIC_KEYpublicKey;PRIVATE_KEYprivateKey;sm2SmUtil.sm2(HexUtil.decodeHex(PRIVATE_KEY),HexUtil.decodeHex(PUBLIC_KEY));}if(StrUtil.isNotBlank(key)){log.info(加密工具密钥-SM4密钥已更新);KEYkey;}}/** * 加密方法Sm2 的专门针对前后端分离非对称秘钥对的方式暴露出去的公钥对传输过程中的密码加个密 * * param str 待加密数据 * return 加密后的密文 * author yubaoshan * date 2022/9/15 21:51 */publicstaticStringdoSm2Encrypt(Stringstr){returnsm2.encryptHex(str,KeyType.PublicKey);}/** * 解密方法 * 如果采用加密机的方法用try catch 捕捉异常返回原文值即可 * * param str 密文 * return 解密后的明文 * author yubaoshan * date 2022/9/15 21:51 */publicstaticStringdoSm2Decrypt(Stringstr){try{// 兼容性处理Hutool要求密文以04开头Uncompressed如果前端传来的是不带04的虽然sm-crypto默认带则补上Stringtextstr;if(StrUtil.isNotBlank(text)!text.startsWith(04)){text04text;}returnsm2.decryptStr(text,KeyType.PrivateKey);}catch(Exceptione){// 降级处理使用原版 antherd sm-crypto 解密兼容性好但性能稍差returnSm2.doDecrypt(str,PRIVATE_KEY);}}/** * 加密方法 * * param str 待加密数据 * return 加密后的密文 * author yubaoshan * date 2022/9/15 21:51 */publicstaticStringdoSm4CbcEncrypt(Stringstr){// SM4 加密 cbc模式Sm4Optionssm4Options4newSm4Options();sm4Options4.setMode(cbc);sm4Options4.setIv(fedcba98765432100123456789abcdef);returnSm4.encrypt(str,KEY,sm4Options4);}/** * 解密方法 * 如果采用加密机的方法用try catch 捕捉异常返回原文值即可 * * param str 密文 * return 解密后的明文 * author yubaoshan * date 2022/9/15 21:51 */publicstaticStringdoSm4CbcDecrypt(Stringstr){// 解密cbc 模式输出 utf8 字符串Sm4Optionssm4Options8newSm4Options();sm4Options8.setMode(cbc);sm4Options8.setIv(fedcba98765432100123456789abcdef);StringdocStringSm4.decrypt(str,KEY,sm4Options8);if(.equals(docString)){log.warn( 字段解密失败返回原文值{},str);returnstr;}else{returndocString;}}/** * 纯签名 * * param str 待签名数据 * return 签名结果 * author yubaoshan * date 2022/9/15 21:51 */publicstaticStringdoSignature(Stringstr){returnHexUtil.encodeHexStr(sm2.sign(StrUtil.utf8Bytes(str)));}/** * 验证签名结果 * * param originalStr 签名原文数据 * param str 签名结果 * return 是否通过 * author yubaoshan * date 2022/9/15 21:51 */publicstaticbooleandoVerifySignature(StringoriginalStr,Stringstr){returnsm2.verify(StrUtil.utf8Bytes(originalStr),HexUtil.decodeHex(str));}/** * 通过杂凑算法取得hash值用于做数据完整性保护 * * param str 字符串 * return hash 值 * author yubaoshan * date 2022/9/15 21:51 */publicstaticStringdoHashValue(Stringstr){returnSmUtil.sm3(str);}/** * 生成SM2公私钥对十六进制字符串 * * return String[]{publicKey, privateKey}均为 hex 格式 */privatestaticString[]generateSm2KeyPair(){SM2sm2GenSmUtil.sm2();StringprivateKeyHexsm2Gen.getDHex();StringpublicKeyHexHexUtil.encodeHexStr(sm2Gen.getQ(false));returnnewString[]{publicKeyHex,privateKeyHex};}/** * 生成 SM4 对称密钥128 bit十六进制字符串 * * return 32 位 hex 字符串 */privatestaticStringgenerateSm4Key(){byte[]keynewbyte[16];newSecureRandom().nextBytes(key);returnHexUtil.encodeHexStr(key);}/** * 调用此方法可生成密钥并测试密钥的正确性 */privatestaticvoidgenerateKeys(){// 1. 生成密钥String[]keyPairgenerateSm2KeyPair();StringpublicKeykeyPair[0];StringprivateKeykeyPair[1];Stringsm4KeygenerateSm4Key();System.out.println( 生成的密钥 );System.out.println(SM2 公钥: publicKey);System.out.println(SM2 私钥: privateKey);System.out.println(SM4 密钥: sm4Key);// 2. 用生成的密钥初始化init(publicKey,privateKey,sm4Key);// 3. 测试 SM2 加解密System.out.println(\n SM2 加解密测试 );Stringsm2PlainHello SM2 加密测试;Stringsm2CipherdoSm2Encrypt(sm2Plain);Stringsm2DecrypteddoSm2Decrypt(sm2Cipher);System.out.println(原文: sm2Plain);System.out.println(密文: sm2Cipher);System.out.println(解密: sm2Decrypted);System.out.println(SM2 测试: (sm2Plain.equals(sm2Decrypted)?通过:失败));// 4. 测试 SM4 加解密System.out.println(\n SM4 加解密测试 );Stringsm4PlainHello SM4 加密测试;Stringsm4CipherdoSm4CbcEncrypt(sm4Plain);Stringsm4DecrypteddoSm4CbcDecrypt(sm4Cipher);System.out.println(原文: sm4Plain);System.out.println(密文: sm4Cipher);System.out.println(解密: sm4Decrypted);System.out.println(SM4 测试: (sm4Plain.equals(sm4Decrypted)?通过:失败));// 5. 测试签名验签System.out.println(\n SM2 签名验签测试 );StringsignPlainHello 签名测试;StringsignaturedoSignature(signPlain);booleanverifieddoVerifySignature(signPlain,signature);System.out.println(原文: signPlain);System.out.println(签名: signature);System.out.println(验签: (verified?通过:失败));}}2.配置读取packagecom.visy.common.prop;importcom.visy.common.util.CommonCryptogramUtil;importjakarta.annotation.PostConstruct;importlombok.Getter;importlombok.Setter;importlombok.extern.slf4j.Slf4j;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.stereotype.Component;/** * 国密加密配置 */Slf4jGetterSetterComponentConfigurationProperties(prefixcrypto)publicclassCryptoProperties{/** * SM2 配置 */privateSm2sm2newSm2();/** * SM4 配置 */privateSm4sm4newSm4();PostConstructpublicvoidinit(){log.info(初始化加密工具密钥...);CommonCryptogramUtil.init(sm2.getPublicKey(),sm2.getPrivateKey(),sm4.getKey());}GetterSetterpublicstaticclassSm2{privateStringprivateKey;privateStringpublicKey;}GetterSetterpublicstaticclassSm4{privateStringkey;}}3.配置文件crypto:sm2:public-key:SM2公钥private-key:SM2私钥sm4:key:SM4密钥4.补充hutool版本 5.8.25

更多文章