当前位置:   article > 正文

记录一次对用户敏感数据的加密存储和脱敏展示实现方式_敏感信息加密显示

敏感信息加密显示

首先先介绍一下mysql中加密和解密函数的使用

函数名       作用
aes_encrypt('需加密的明文', '密钥')加密操作
aes_decrypt('加密以后的密文', '密钥')解密操作
hex(’字符串‘)将字符串转换为十六进制
unhex('十六进制字符串')将十六进制字符串转换为原格式的字符串

代码演示这四个函数的效果

  1. -- HEX()和UNHEX()
  2. SELECT HEX('这是一个字符串') FROM DUAL
  3. -- E8BF99E698AFE4B880E4B8AAE5AD97E7ACA6E4B8B2
  4. -- SELECT unhex(HEX('这是一个字符串')) FROM DUAL
  5. SELECT unhex('E8BF99E698AFE4B880E4B8AAE5AD97E7ACA6E4B8B2') FROM DUAL
  6. -- 这是一个字符串
  7. -- aes_encrypt() 和 aes_decrypt()
  8. SELECT AES_ENCRYPT('dasd','qwertyuipfasdfgh') FROM DUAL
  9. -- �L�UXٶTc �_w>
  10. -- 得到的是乱码,怎么解决呢,这就要使用我们上面提到的函数进行转换了,如果不转换,那么加密和解密都是报错的
  11. --
  12. SELECT HEX(AES_ENCRYPT('dasd','qwertyuipfasdfgh')) FROM DUAL
  13. -- 9104C8129EE23A525D96E3A0257C12B7
  14. -- 通过转换为十六进制了,那么在解密的时候也需要将十六进制转换为原来的格式
  15. SELECT AES_DECRYPT(UNHEX('9104C8129EE23A525D96E3A0257C12B7'),'qwertyuipfasdfgh')
  16. -- dasd
  17. -- 到此加密解密的演示完成

深究乱码原因可参考:

MySql在使用AES_ENCRYPT或者ENCODE加密时,中文乱码问题(数据库正常,在java代码和页面中变成问号乱码)_tiancao222的博客-CSDN博客_mysql aes 乱码

加密存储身份证号

        这儿通过mybatis进行展示,通过修改mapper映射文件的方式。

  1. <insert id="xxxx" parameterType="xxx">
  2. insert into 表名
  3. <trim prefix="(" suffix=")" suffixOverrides=",">
  4. <if test="idCardNo != null">
  5. id_card_no,
  6. </if>
  7. </trim>
  8. <trim prefix="values (" suffix=")" suffixOverrides=",">
  9. <!-- 敏感信息加密,密钥aes+HEX十六进制 -->
  10. <if test="idCardNo != null">
  11. hex(aes_encrypt( #{idCardNo} ,'${@com.cc.ext.common.ConstantsExt@MYSQL_SECRET_KEY}')),
  12. </if>
  13. </trim>
  14. </insert>

介绍一下mybatis中引用外部java代码中的变量的方式(写法):

'${@com.cc.ext.common.ConstantsExt@MYSQL_SECRET_KEY}'

  1. package com.cc.ext.common;
  2. public class ConstantsExt extends Constants {
  3. // 加密解密密文
  4. public static final String MYSQL_SECRET_KEY = "qazwsxedcrfvtgby";
  5. }

第一个@是全限定类名,第二个@指向的就是这个具体的变量

数据插入后的效果

脱敏展示

        在数据库中存放的是加密后的十六进制数,我们不可能在前台展示这个吧。所以说,在后台我们需要对这个数据进行解密后脱敏在传递给前端。

创建加密解密的工具类

  1. public class AesUtils {
  2. /**
  3. * 密钥,ConstantsExt.MYSQL_SECRET_KEY是密钥常量
  4. */
  5. private static final byte[] key = ConstantsExt.MYSQL_SECRET_KEY.getBytes(StandardCharsets.UTF_8);
  6. /**
  7. * 初始化加密(默认的AES加密方式)
  8. */
  9. private static final SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
  10. /**
  11. * 加密
  12. *
  13. * @param str 加密之前的字符串
  14. * @return
  15. */
  16. public static String encryptHex(String str) {
  17. return aes.encryptHex(str);
  18. }
  19. /**
  20. * 解密
  21. *
  22. * @param str 加密后的字符串
  23. * @return
  24. */
  25. public static String decryptStr(String str) {
  26. return aes.decryptStr(str);
  27. }
  28. }

脱敏的工作可以自己写正则匹配也可以使用工具类,我这儿图方便使用的是hutool工具包中的脱敏工具。

Hutool参考文档

  1. // 使用
  2. DesensitizedUtil.idCardNum("51343620000320711X", 5, 2);
  3. // 51343***********1x
  4. // 前五个字符和后两个字符展示,其余***代替

上面就是hutool的简单使用了,因为我们的数据库中存放的数据是加密的,那么首先需要对查询到的数据进行解密操作,就可以用到我们自定义的工具类,当然也可以使用hutool自带的工具类。

  1. String deStr = AesUtils.decryptStr('数据库中查询出来的加密后的身份证号');
  2. String desensitizationStr = DesensitizedUtil.idCardNum(deStr , ConstantsExt.DESEN_START_INDEX, ConstantsExt.DESEN_END_INDEX);
  3. // 5453*************1X

前端展示效果

 支持模糊查询

        很多时候我们需要模糊查询的功能,但是在数据库中的数据又是通过以上方式加密的,此时还怎么才能做到模糊查询呢?

        其实实现的思路也很简单,就是我们先对数据库中的数据进行解密,之后呢和前端传递过来的参数进行模糊匹配即可。

SELECT 字段 FROM 表名 WHERE AES_DECRYPT(UNHEX('数据库中的密文'), '密钥') LIKE CONCAT('%' , '明文' , '%')

      

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/702914
推荐阅读
相关标签
  

闽ICP备14008679号