柏竹 柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档

柏竹

奋斗柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档
  • Java基础

  • JavaWeb

  • 拓展技术

  • 框架技术

  • 数据库

  • 数据结构

  • Spring

  • SpringMVC

  • SpringBoot

  • SpringClound

  • Ruoyi-Vue-Plus

    • ruoyi-vue-plus-基础功能
    • ruoyi-vue-plus-权限控制
    • ruoyi-vue-plus-表格操作
    • ruoyi-vue-plus-缓存功能
    • ruoyi-vue-plus-日志功能
    • ruoyi-vue-plus-线程相关
    • ruoyi-vue-plus-OSS功能
    • ruoyi-vue-plus-代码生成功能
    • ruoyi-vue-plus-多数据源
    • ruoyi-vue-plus-任务调度
    • ruoyi-vue-plus-监控功能
    • ruoyi-vue-plus-国际化
    • ruoyi-vue-plus-XSS功能
    • ruoyi-vue-plus-防重幂&限流 功能
    • ruoyi-vue-plus-推送功能
    • ruoyi-vue-plus-序列化功能
    • ruoyi-vue-plus-数据加密
      • 数据加密
      • 数据库加密
        • 应用
        • 实现原理
        • 数据加密
        • 数据解密
        • Mybatis拦截
    • ruoyi-vue-plus-单元测试
    • ruoyi-vue-plus-前端插件
    • ruoyi-vue-plus-前端工具篇
    • ruoyi-vue-plus-部署篇
    • ruoyi-vue-plus-前端篇
    • ruoyi-vue-plus-后端工具篇
    • ruoyi-vue-plus-框架篇
    • ruoyi-vue-plus-问题解决
  • 后端
  • Ruoyi-Vue-Plus
柏竹
2024-05-01
目录

ruoyi-vue-plus-数据加密

# 数据加密

工具类应用 点击跳转

# 数据库加密

ruoyi-vue-plus 数据库加密是通过 Mybatis拦截器实现 , 在处理字段时 有EncryptField注解的字段会进行加密处理 . 当数据添加时加密 , 获取时解密

支持加密算法 : BASE64 AES RSA SM2 SM4

参考文档

  • ruoyi-vue-plus数据库加密应用文档 : https://plus-doc.dromara.org (opens new window)
  • Liu_York博主Mybatis拦截器笔记 : https://blog.csdn.net/Liu_York (opens new window)

# 应用

  1. 配置 秘钥 & 类型
  2. 对象属性写上 EncryptField注解 , 参数标识 加密类型
  3. 执行SQL , 新增、修改、查询 , 即可实现存储加密 , 获取解密

提示

查询解密仅限于当前实体类 , 不支持继承实体类方式解密

# 实现原理

理解过程的前提可以看下 Mybatis拦截器 大概运作

# 数据加密

数据加密拦截处理的时期是 参数传递设置时进行处理 , 注解配置项 (根据Signature控制拦截时期)

@Intercepts({@Signature(
    type = ParameterHandler.class,
    method = "setParameters",
    args = {PreparedStatement.class})
})

数据加密过程 :

  1. 执行传参SQL时 , 进入 *plugin()*代理方法 , 判断 ParameterHandler处理类型

  2. 获取当前参数对象(SQL传递的参数) , 该对象不能为空并且也不能是字符串 , 必须是对象才进行加密处理

  3. 对象加密处理 *encryptHandler()*方法 , 判断 以下三种类型 以及拆箱过程

    null类型不处理 / Map类型取值递归拆箱加密 / List类型循环取值递归拆箱加密

    • Null值 : 跳出加密处理
    • Map类型 : 取出所有value值递归执行
    • List类型 : 判空 , 非空则获取List第一个对象 , 并判断当中的字段是否包含 EncryptField加密注解 , 只要第一个含有EncryptField加密注解 , 那么循环List递归执行
  4. 注册式反射获取对象字段 , 采用 EncryptorManager#getFieldCache() 获取对象所有字段

    EncryptorManager#getFieldCache() 注册式获取对象反射的字段 (首次反射获取 , 下次缓存获取)

  5. 循环对象的所有字段 , 加密处理

    1. 判空处理 , 空则 跳过循环
    2. 获取对象注解 (加密类型以及信息) , 并根据注解构建 EncryptContext上下文对象
    3. 注册式获取加解者 , 根据 EncryptContext上下文对象 和 加密配置信息 反射获取 (相同的上下文配置 , 获取相同的加解者)
    4. 使用加解者加密处理 , 加密其他配置信息可直接在 EncryptContext上下文对象获取
    5. 对该字段反射设置加密的值

注册式获取

注册式获取 是减少频繁实例和反射次数为目的一种优化方案 , 首次访问会进行缓存起来 , 下次获取时直接取缓存中的已注册对象 . 存储形式一般是Map , key一般是 class类型、配置对象 等..

# 数据解密

数据解密拦截处理的时期是 SQL执行出结果集 , 注解配置项 (根据Signature控制拦截时期)

@Intercepts({@Signature(
    type = ResultSetHandler.class,
    method = "handleResultSets",
    args = {Statement.class})
})

数据解密过程 : (步骤3-5 与加密的相同)

  1. SQL执行出结果值时 , 进入 *plugin()*代理方法 , 采用 Plugin.wrap(target, this)绑定关联代理拦截器方法intercept()

  2. 拦截后置处理(SQL执行出结果) , 在*intercept()*方法中 , 执行 *invocation.proceed()*方法得到结果

  3. 解密结果集处理 decryptHandler() , 判断 以下三种类型 以及拆箱过程

    null类型不处理 / Map类型取值递归拆箱加密 / List类型循环取值递归拆箱加密

    • Null值 : 跳出加密处理
    • Map类型 : 取出所有value值递归执行
    • List类型 : 判空 , 非空则获取List第一个对象 , 并判断当中的字段是否包含 EncryptField加密注解 , 只要第一个含有EncryptField加密注解 , 那么循环List递归执行
  4. 注册式反射获取对象字段 , 采用 EncryptorManager#getFieldCache() 获取对象所有字段

    EncryptorManager#getFieldCache() 注册式获取对象反射的字段 (首次反射获取 , 下次缓存获取)

  5. 循环对象的所有字段 , 解密处理

    1. 判空处理 , 空则 跳过循环
    2. 获取对象注解 (解密类型以及信息) , 并根据注解构建 EncryptContext上下文对象
    3. 注册式获取加解者 , 根据 EncryptContext上下文对象 和 解密配置信息 反射获取 (相同的上下文配置 , 获取相同的加解者)
    4. 使用加解者加密处理 , 加密其他配置信息可直接在 EncryptContext上下文对象获取
    5. 对该字段反射设置加密的值
  6. 返回结果集 , *intercept()*方法 解密的结果集直接返回即可 (该对象地址映射的值已被解密处理)

# Mybatis拦截

概念

  • Intercepts注解 , 标识拦截类 , 参数Signature注解控制拦截时期

  • Signature注解 , 标识具体的拦截时期

    type(指定拦截类)、method(指定拦截类中的时期)、ages(拦截方法的参数)

  • Interceptor接口 , Mybatis拦截器实现的接口 , 含以下3个实现方法

    • *intercept(Invocation invocation)*方法 , 拦截前置和后置处理(前后分界线为 *invocation.proceed()*继续执行方法) , Invocation 含有Signature注解的标识信息 target (理解为type)、method、ages . 可以得知哪个时期触发拦截 , 日志场景

    • plugin()方法 , 代理拦截时期的处理过程 , 不处理则返回本身

      PS : 如果拦截了多个时期(Signature) , 那么代理处理前建议判断 参数对象类型 , 以免交叉处理现象

    • setProperties()方法 , 加载核心配置文件时设置变量参数

提示

*plugin()*方法 是 返回代理对象的拦截器 或 不处理 , 返回的值有以下两种形式

  1. 返回对象本身 target : 不处理拦截器代理的方法 intercept()
  2. 返回 Plugin.wrap(target, this) : 创建并绑定代理拦截器方法 intercept() , 但拦截器方法一定调用 invocation.proceed() 方法执行

Signature注解 标识信息

type 拦截类 method 拦截方法 说明
Executor update 库前后操作拦截
ParameterHandler getParameterObject、setParameters 参数拦截
ResultSetHandler handleResultSets、handleCursorResultSets、handleOutputParameters 结果集拦截
StatementHandler prepare、parameterize、batch、update、query、queryCursor、getBoundSql、getParameterHandler SQL语句拦截
#ruoyi-vue-plus#数据加密

← ruoyi-vue-plus-序列化功能 ruoyi-vue-plus-单元测试→

最近更新
01
HTTPS自动续签
10-21
02
博客搭建-简化版(脚本)
10-20
03
ruoyi-vue-plus-部署篇
07-13
更多文章>
Theme by Vdoing | Copyright © 2019-2024 | 桂ICP备2022009417号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式