1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 使用mybatis拦截器实现字段加密解密

使用mybatis拦截器实现字段加密解密

时间:2023-07-22 12:23:00

相关推荐

使用mybatis拦截器实现字段加密解密

前言

.项目中我们存储一些用户信息的使用后根据规定,不可以存储明文,尤其是密码,实现的办法有好多种,今天承接上一篇文章mybatis拦截器,利用拦截器实现使用注解的方式在数据插入前进行加密,查询是自动进行解密的功能,前面提到过mybatis-plus拦截器用起来更方便一点,但是有个问题就是,如果使用了mybatis-plus拦截器就没办法在换其他的框架了

声明

此功能是根据自己需求改造其他大佬的项目而来(以下链接是原项目),目前仅用于自己测试没有问题,未经实际环境验证,请大家斟酌使用!mybatis-plus其实也支持此功能,但是他是收费项

/weixin_43655425/article/details/121394246

与原项目不同的是增加了对非对称加密算法的支持, 目前仅在里面实现的SM2,SM3,SM4三中算法,理论上加上非对称加密算法后应该是支持绝大多数算法,可根据需求直接更改源代码或实现ICrypto接口自定义

下载连接

里面的encrypt是实现加密注解的源代码,encrypt_demo为加密注解的演示demo

/s/f683e7cf5e9143

配置

增加配置项,目前的配置是支持国密SM2,SM3,SM4,如果不配置,将使用默认配置进行加密,对于密钥对的生成,提供了GenerateKeyPair工具类生成密钥对

#加密注解配置,如果不配置将使用默认配置加密privacy:crypto:#密钥,用于SM4对称加密,随机16位字符串即可key: qwerdhdhfgcbshur#私钥公钥,用于SM2费对称加密,可用测试类中的方法生成替换privateKey: 30819300301306072a8648ce3d06082a811ccf5501822d04793077010420699d3f230b7ab5fe4520b550fb021585b648950ba1ec988a0730fa95fa809f26a00a06082a811ccf5501822da1440342000487a23a1bde2da2d7004dbfc9101aa30042880593108e99d7b47c72c139abe8159174dcac41c998b818ff9cec508fb9a732dbbd1f957d8fc423c164d42bb3d04cpublicKey: 3059301306072a8648ce3d06082a811ccf5501822d0342000487a23a1bde2da2d7004dbfc9101aa30042880593108e99d7b47c72c139abe8159174dcac41c998b818ff9cec508fb9a732dbbd1f957d8fc423c164d42bb3d04c

/*** 生成SM2非对称加密算法的密钥对,可用于替换yml配置文件中的 privateKey 和 publicKey** @author zzt* @version 1.0.0* @date /8/5 16:15*/public class GenerateKeyPair {public static void main(String[] args) {KeyPair pair = SecureUtil.generateKeyPair("SM2");byte[] privateKey = pair.getPrivate().getEncoded();byte[] publicKey = pair.getPublic().getEncoded();String privateKeyStr = HexUtil.encodeHexStr(privateKey);String publicKeyStr = HexUtil.encodeHexStr(publicKey);System.out.println("privateKey: " + privateKeyStr);System.out.println("publicKey: " + publicKeyStr);}}

用法

直接将注解添加到需要加密的字段上即可,其中注解中有三个参数需要注意含义:

key:是对插加密的密钥16位字符串即可,该项如果自定义进行了配置,当解密时需要使用相同的密钥否则无法解密

algorithm: 选择加密算法类型

iCrypto:加密实现类,当默认算法不满足是可自定义算法加密类

/*** 用户信息** @author zzt* @version 1.0.0* @date /8/4 11:02*/@TableName("encrypt_demo")@Data@Accessors(chain = true)public class EncryptDemoEntity {@TableIdprivate Long id;/*** 指定SM2,非对称加密算法,该算法需要配置公钥和私钥,可在配置文件中配置*/@FieldEncrypt(algorithm = Algorithm.SM2)@TableField(value = "USER_NAME")private String userName;/*** 使用默认的SM4加密算法,该算法可以被解密*/@FieldEncrypt@TableField(value = "PHONE_NUM")private String phoneNum;/*** 使用自定义SM3算法,该算法不可以被解密,查询时将返回密文*/@FieldEncrypt(algorithm = Algorithm.SM3)@TableField(value = "PASS_WORD")private String passWord;}

测试方法及结果

@SpringBootTest@RunWith(SpringRunner.class)class EncryptDemoApplicationTests {@Autowiredprivate EncryptDemoMapper encryptDemoMapper;/*** 一般情况下使用默认SM4算法和指定SM3算法,SM2算法加密*/@Testpublic void encryptTest1() {EncryptDemoEntity entity = new EncryptDemoEntity();Long id = System.currentTimeMillis();entity.setId(id).setPhoneNum("15555555555").setUserName("admin").setPassWord("111111");encryptDemoMapper.insert(entity);System.out.println("加密后的结果: " + entity);//加密后的结果: EncryptDemoEntity(id=1659596682578, userName=040EA7241AF8C0FA5F8816B3F6DBFC6A02CFF32BE7EE8EEF741183E64267DACC6773478A97D8CB8B60FFA9D3F4B691F2B96F5EB607A7995336FCB3CF5AA635E6EE58085EE9FDA5F7EBA29F7968E8FF6D47D3A111712E69801489EDE0D3F42F507322F09A1154, phoneNum=90cd9092b5c643ef966346ce1e3ad224, passWord=c7f66beee198fb411c8623e53cbbc6eb1e0f078b5d68ed7f10d02ffb0af46d44)entity = encryptDemoMapper.selectById(id);System.out.println("解密后的结果: " + entity);//password字段使用的是SM3算法加密,不可被解密,所以返回的是密文//解密后的结果: EncryptDemoEntity(id=1659596682578, userName=admin, phoneNum=15555555555, passWord=c7f66beee198fb411c8623e53cbbc6eb1e0f078b5d68ed7f10d02ffb0af46d44)}/*** 给SM4对称加密算法指定自定义密钥*/@Testpublic void encryptTest2() {EncryptDemoVo vo = new EncryptDemoVo();Long id = System.currentTimeMillis();vo.setId(id).setUserName("root").setPhoneNum("15777777777").setPassWord("222222");//如果把vo的数据复制到entity,vo的加密配置将会被entity覆盖,需要注意encryptDemoMapper.insertVo(vo);System.out.println("加密后的结果: " + vo);//加密后的结果: EncryptDemoVo(id=1659597730091, userName=043E4074164748F73C108368A3C9017FE5396B807743CA536603FD1990584FC1A02ADADF23FBCD508B62788712CD85CF145248086E6D7A873E002B07405E9D0D2618C097D237445A4F8641368EA75257A916C77007F61424D966D574EB199F37AB1A4C54DD, phoneNum=8a089016eaba292348b6c81aeb170a00, passWord=8b30ba1c30168d83a5ef274f7b27f9aea4cda203ca0fc8965c1c5316dfb20309)vo = encryptDemoMapper.selectVoById(id);System.out.println("使用自定义密钥解密后的结果: " + vo);//使用自定义密钥解密后的结果: EncryptDemoVo(id=1659597730091, userName=root, phoneNum=15777777777, passWord=8b30ba1c30168d83a5ef274f7b27f9aea4cda203ca0fc8965c1c5316dfb20309)EncryptDemoTwoVo encryptDemoTwoVo = encryptDemoMapper.selectEncryptTwoVo(id);System.out.println("使用默认密钥解密后的结果: " + encryptDemoTwoVo);//注意这里EncryptDemoTwoVo里面的phoneNum使用的是默认密钥,但是这条数据我们使用的是自定义密钥加密的,所以解密结果是无法成功的,会报 BadPaddingException: pad block corrupted的异常信息!//使用默认密钥解密后的结果: EncryptDemoTwoVo(id=1659598162187, userName=root, phoneNum=8a089016eaba292348b6c81aeb170a00, passWord=8b30ba1c30168d83a5ef274f7b27f9aea4cda203ca0fc8965c1c5316dfb20309)}/*** 生成SM2非对称加密算法的密钥对,可用于替换yml配置文件中的 privateKey 和 publicKey*/@Testpublic void generateKeyPair() {KeyPair pair = SecureUtil.generateKeyPair("SM2");byte[] privateKey = pair.getPrivate().getEncoded();byte[] publicKey = pair.getPublic().getEncoded();String privateKeyStr = HexUtil.encodeHexStr(privateKey);String publicKeyStr = HexUtil.encodeHexStr(publicKey);System.out.println("privateKey: " + privateKeyStr);System.out.println("publicKey: " + publicKeyStr);}}

如有发现什么不足或可以改进的地方,欢迎指正讨论

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。