好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

MyBatis-Plus如何实现自动加密解密

MyBatis-Plus 自动加密解密

通过使用MyBatis的typeHandler功能,对入参和出参进行处理,实现无缝加密解密(将明文加密后保存至数据库;从数据库读取时,自动将密文解密成明文)

实现TypeHandler

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

@Slf4j

public class UserTypeHandler extends BaseTypeHandler<Object> {

     /**

      * 非空字段加密

      * @param preparedStatement

      * @param i

      * @param parameter

      * @param jdbcType

      * @throws SQLException

      */

     @Override

     public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object parameter, JdbcType jdbcType) {

         try {

             if (StrUtil.isBlank((String) parameter)) {

                 return ;

             }

             // todo 加密操作

             String encrypt = "" ;

             preparedStatement.setString(i, encrypt);

         } catch (Exception e) {

             log.error( "typeHandler加密异常:" + e);

         }

     }

     /**

      * 非空字段解密

      * @param resultSet

      * @param columnName

      * @return

      * @throws SQLException

      */

     @Override

     public Object getNullableResult(ResultSet resultSet, String columnName) throws SQLException {

         String col = resultSet.getString(columnName);

         try {

             if (StrUtil.isBlank(col)) {

                 return col;

             }

             // todo 对结果col进行解密操作

             return "" ;

         } catch (Exception e) {

             log.error( "typeHandler解密异常:" + e);

         }

         return col;

     }

     /**

      * 可空字段加密

      * @param resultSet

      * @param columnIndex

      * @return

      * @throws SQLException

      */

     @Override

     public Object getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {

         String col = resultSet.getString(columnIndex);

         try {

             if (StrUtil.isBlank(col)) {

                 return col;

             }

             // todo 对结果col进行解密操作

             return "" ;

         } catch (Exception e) {

             log.error( "typeHandler解密异常:" + e);

         }

         return col;

     }

     /**

      * 可空字段解密

      * @param callableStatement

      * @param columnIndex

      * @return

      * @throws SQLException

      */

     @Override

     public Object getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {

         String col = callableStatement.getString(columnIndex);

         try {

             if (StrUtil.isBlank(col)) {

                 return col;

             }

             // todo 对结果col进行解密操作

             return "" ;

         } catch (Exception e) {

             log.error( "typeHandler解密异常:" + e);

         }

         return col;

     }

}

添加注解

在对应的实体类中

在 @TableName 注解中,设置 autoResultMap 参数为true 在需要加解密的字段上,添加注解 @TableField(typeHandler = UserTypeHandler.class)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@Data

@TableName (value = "t_user" , autoResultMap = true )

public class UserEntity {

     /**

      * 主键自增

      */

     @TableId (type = IdType.AUTO)

     private Integer id;

     private String name;

     private Integer age;

     @TableField (typeHandler = UserTypeHandler. class )

     private String password;

     private String role;

}

查询加密字段

MyBatis-Plus的QueryWrapper在查询加密字段时,并不会进入TypeHandler,需要手写sql,指定字段进行TypeHandler中的流程。

注解方式

?

1

2

3

4

5

@Results (id= "resultMap" , value = {

     @Result (column = "password" , property = "password" , typeHandler = UserTypeHandler. class )

})

@Select ( "select * from t_user where password = #{password, typeHandler=com.mybatisdemo.config.UserTypeHandler}" )

List<UserEntity> list(UserQuery userQuery);

XML方式

?

1

2

3

4

5

6

< resultMap id = "userMap" type = "com.mybatisdemo.entity.UserEntity" >

     < result column = "password" property = "password" typeHandler = "com.mybatisdemo.config.UserTypeHandler" />

</ resultMap >

< select id = "list" resultMap = "userMap" >

     select * from t_user where password = #{password,typeHandler=com.mybatisdemo.config.UserTypeHandler}

</ select >

MyBatis-Plus 敏感数据的加密

最近在做项目,需要实现对身份证,密码等敏感数据的加密,即不能以明文存储密码到数据库。

上网查了一下资料,解决办法如下:

写加密解密的工具类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

import org.apache测试数据mons.codec.binary.Base64;

import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

public class AES {

     // 密钥

     public static String key = "AD42F6697B035B7580E4FEF93BE20BAD" ;

     private static String charset = "utf-8" ;

     // 偏移量

     private static int offset = 16 ;

     private static String transformation = "AES/CBC/PKCS5Padding" ;

     private static String algorithm = "AES" ;

     /**

      * 加密

      *

      * @param content

      * @return

      */

     public static String encrypt(String content) {

         return encrypt(content, key);

     }

     /**

      * 解密

      *

      * @param content

      * @return

      */

     public static String decrypt(String content) {

         return decrypt(content, key);

     }

     /**

      * 加密

      *

      * @param content 需要加密的内容

      * @param key     加密密码

      * @return

      */

     public static String encrypt(String content, String key) {

         try {

             SecretKeySpec skey = new SecretKeySpec(key.getBytes(), algorithm);

             IvParameterSpec iv = new IvParameterSpec(key.getBytes(), 0 , offset);

             Cipher cipher = Cipher.getInstance(transformation);

             byte [] byteContent = content.getBytes(charset);

             cipher.init(Cipher.ENCRYPT_MODE, skey, iv); // 初始化

             byte [] result = cipher.doFinal(byteContent);

             return new Base64().encodeToString(result); // 加密

         } catch (Exception e) {

             // LogUtil.exception(e);

         }

         return null ;

     }

     /**

      * AES(256)解密

      *

      * @param content 待解密内容

      * @param key     解密密钥

      * @return 解密之后

      * @throws Exception

      */

     public static String decrypt(String content, String key) {

         try {

             SecretKeySpec skey = new SecretKeySpec(key.getBytes(), algorithm);

             IvParameterSpec iv = new IvParameterSpec(key.getBytes(), 0 , offset);

             Cipher cipher = Cipher.getInstance(transformation);

             cipher.init(Cipher.DECRYPT_MODE, skey, iv); // 初始化

             byte [] result = cipher.doFinal( new Base64().decode(content));

             return new String(result); // 解密

         } catch (Exception e) {

             //LogUtil.exception(e);

         }

         return null ;

     }

     public static void main(String[] args) throws Exception {

         String s = "hello world" ;

         // 加密

         System.out.println( "加密前:" + s);

         String encryptResultStr = encrypt(s);

         System.out.println( "加密后:" + encryptResultStr);

         // 解密

         System.out.println( "解密后:" + decrypt(encryptResultStr));

     }

}

继承BaseTypeHandler ,实现对数据的转换

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

import org.apache.ibatis.type.BaseTypeHandler;

import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

/**

  * @author starmark

  * @date 19-12-17  下午8:38

  */

public class AESEncryptHandler extends BaseTypeHandler {

     @Override

     public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {

         ps.setString(i, AES.encrypt((String)parameter));

     }

     @Override

     public String getNullableResult(ResultSet rs, String columnName) throws SQLException {

         String columnValue = rs.getString(columnName);

         return AES.decrypt(columnValue);

     }

     @Override

     public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {

         String columnValue = rs.getString(columnIndex);

         return AES.decrypt(columnValue);

     }

     @Override

     public String getNullableResult(CallableStatement cs, int columnIndex)

             throws SQLException {

         String columnValue = cs.getString(columnIndex);

         return AES.decrypt(columnValue);

     }

}

有po类中,实现相关类型注解

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

  * 用户管理

  */

@Data

@EqualsAndHashCode (callSuper = false )

@TableName (autoResultMap = true )

public class SysOrgUser extends BaseUpdateModel {

     /**

      * 登陆帐户

      */

     private String loginName;

     /**

      * 密码

      */

     @TableField (typeHandler = AESEncryptHandler. class )

     private String password;

至此,密码等敏感信息已处理好。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/YW_Danny/article/details/120031966

查看更多关于MyBatis-Plus如何实现自动加密解密的详细内容...

  阅读:81次