Logo
数据防篡改

数据防篡改 #

随着信息化和数字化的飞速发展,数据安全的重要性与日俱增。数据安全存在多种风险场景,比如数据遭受恶意的攻击或者人为失误的修改数据等。这些问题可能会导致数据不一致或者严重的会导致数据错误,从而影响企业信息安全和用户个人信息安全。由此可见,确保数据的安全性和准确性尤为重要。数据防篡改提供对关键数据的摘要和篡改验证,从而实现关键数据的可靠性保护。 对于涉及到客户的所有安全信息或者商业机密数据,都需要进行防篡改操作,从而保证数据的安全性。

对于数据防篡改的需求,在现实业务场景中一般分为一下两种情况:

  1. 新业务上线,对于安全性要求较高的数据,例如身份证、银行卡号等信息,需要通过不可逆的摘要算法生成唯一的防篡改列,当机密信息被篡改时,可以第一时间发现。因为是全新系统,因而没有存量数据清洗问题,所以实现相对简单。

  2. 已上线业务,目前系统中已经有大量存量数据存储在数据库中,甚至有部分数据已经做了加密安全防护。防篡改可以再此基础上再多加一层防护,让数据安全更为牢固。这种场景一般需要处理 3 个问题:

  • 历史数据需要如何进行防篡改摘要处理,即防篡改洗数。
  • 如何能在不改动业务 SQL 和逻辑情况下,将新增数据进行防篡改处理,并将防篡改列信息存储到数据库;在使用时,能够进行防篡改数据校验。
  • 支持已经加密的数据进行防篡改操作。

概述 #

SphereEx-DBPlusEngine 根据业界对防篡改的需求及业务改造痛点,提供了一套完整、安全、透明化、低改造成本的数据防篡改整合解决方案。 目前 SphereEx-DBPlusEngine 内置了 HMAC、MD5、SHA 和 SM3 防篡改摘要算法,支持 MySQL、PostgreSQL、openGauss、Oracle 等常见数据库类型。

在真实业务场景中,相关业务开发团队则往往需要针对公司安全部门需求,自行实行并维护一套防篡改系统。 而当防篡改场景发生改变时,比如修改防篡改列、修改防篡改算法时,自行维护的防篡改系统往往又面临着重构或修改风险。 此外,对于已经上线的业务,在不修改业务逻辑和 SQL 的情况下,透明化、安全低风险地实现无缝进行数据防篡改改造也相对复杂。

为了提升功能的易用性,SphereEx-DBPlusEngine 数据防篡改插件提供了云端密钥管理、洗数以及反洗数能力。

目前 SphereEx-DBPlusEngine 数据防篡改插件所支持的数据库产品为 MySQL、PostgreSQL、openGauss、SQLServer、Oracle、Dameng 等,具体支持版本如下。

数据库版本支持
1MySQL5.7.x ~ 8.x
2PostgreSQL9.6 及以上版本
3openGauss2.1.0 及以上版本
4SQLServer15.0 及以上版本
5Oracle10g 及以上版本
6DamengDM8 及以上版本

基本概念 #

  • 逻辑表 用于进行防篡改操作的表。

  • 摘要组(digestGroups) 对一张逻辑表上的多个逻辑列分别进行摘要配置。

  • 逻辑列(防篡改列 dataIntegrityColumn)

用于计算摘要列值的逻辑名称,是 SQL 中列的逻辑标识。

  • 摘要列(digestColumn)

根据防篡改配置的摘要算法,对逻辑列进行摘要处理后,将摘要结果存储到摘要列里。

  • 摘要算法(digester)

指对数据进行摘要过程中,所使用的具体的摘要算法,如 SHA 及 MD5 等。

  • 摘要洗数(digesting)

对数据库中未进行防篡改的数据进行批量防篡改摘要处理。

  • 密钥管理

摘要算法密钥的存放及管理方式。

特色能力 #

  • 云端密钥管理

由于防篡改摘要的 key 以明文形式配置在 props 文件中存在安全隐患,SphereEx-DBPlusEngine 可通过增加 AWS 云端密钥管理功能来管理防篡改的 key。例如利用 AWS 的 secretKey 功能保存密钥,从而提升整个防篡改的安全性和便捷性。 程序在初始化防篡改算法时,会同 AWS 建立连接,从而获取存储在 AWS 中的相关密钥,然后将防篡改密钥存储在算法中。在整个数据防篡改的过程中不涉及与云端的网络交互。

  • 防篡改洗数

目前 SphereEx-DBPlusEngine 已经提供了防篡改的解决方案,对于新表新业务而言,直接使用防篡改规则配置即可,但是对于已有数据表,就需要将这些表中的逻辑列值进行洗数,转化为防篡改摘要内容,SphereEx-DBPlusEngine 提供了完整的洗数方案。 防篡改洗数通过 DistSQL 来触发洗数作业,程序收到洗数的请求之后,会根据当前的洗数规则以及防篡改规则创建洗数作业。 洗数作业主要由两部分构成,一部分是查询任务,一部分是更新任务,查询任务负责查询用户的表数据并获取需要摘要的逻辑列字段,然后推送到通道中; 更新任务则从通道中获取数据,并防篡改摘要更新。 整个任务的创建以及执行过程都会与治理中心进行交互,因此用户可以通过相关 DistSQL 来查询任务进度以及清理任务。

  • 防篡改重洗数

对于更换防篡改摘要算法或更换密钥等情况,可通过 SphereEx-DBPlusEngine 来重新进行防篡改洗数。重洗数方案会调用使用新的防篡改密钥进行洗数流程。

在以上洗数过程中,SphereEx-DBPlusEngine 支持断点续传的能力,为用户提供更好地洗数体验。

适用场景 #

  • 新上线业务的的数据防篡改场景

对于想要快速上线新业务,同时又需要保证机密数据的完整性,通过 SphereEx-DBPlusEngine 防篡改插件,用户可以快速完成数据的防篡改加固,无需自行开发复杂的防篡改系统。同时 SphereEx-DBPlusEngine 防篡改具备的灵活性,也能够帮助客户避免防篡改场景变更带来的复杂重构和修改风险。

  • 已上线业务的数据进行防篡改改造场景

对于已经上线的成熟业务,用户不仅需要考虑历史数据的清洗,还需要考虑新旧功能的切换。 通过 SphereEx-DBPlusEngine 防篡改插件,用户可以方便地完成系统的防篡改改造,它还能够帮助用户安全快速地切换新旧功能,对存量数据进行防篡改清洗。用户无需改动任何业务逻辑和 SQL 就能够透明化地使用防篡改功能。并且对于之前已经使用 SphereEx-DBPlusEngine 加密功能的应用,也能做到无缝添加防篡改功能。

使用前提 #

SphereEx-DBPlusEngine 尽可能让业务无感完成防篡改改造,现阶段有部分功能存在受限情况,因此在防篡改设计阶段,需调研业务系统需要根据防篡改限制进行提前评估,SphereEx-DBPlusEngine 具体使用限制见下文。

使用限制 #

  • 对于配置多个逻辑列摘要到一个摘要列的场景,更新时需要将所有涉及的逻辑列更新,否则 SphereEx-DBPlusEngine 会查询数据库补充缺失的逻辑列值进行防篡改摘要操作,对性能有一定影响;
  • 仅支持通过 Pipeline 任务触发防篡改校验,对于 Select 查询的实时防篡改校验只支持简单 SQL(只涉及一张表,不包含 Join 和子查询)。

优势 #

  • 自动化 & 透明化数据防篡改过程,用户无需关注防篡改中间实现细节。
  • 内置多种防篡改摘要算法,用户仅需简单配置即可使用。
  • 提供防篡改算法 API 接口,用户可实现接口,从而使用自定义防篡改摘要算法进行数据防篡改操作。
  • 针对已上线业务,可以支持动态进行防篡改洗数,避免停机等待。

原理介绍 #

SphereEx-DBPlusEngine 通过对用户输入的 SQL 进行解析,并依据用户提供的防篡改规则对 SQL 进行改写,从而实现对原文数据进行防篡改,并将防篡改摘要列数据存储到底层数据库。 后续用户可以通过 Pipeline 任务触发防篡改校验任务,校验数据的完整性。

SphereEx-DBPlusEngine 自动化 & 透明化了数据防篡改过程,让用户无需关注数据防篡改的实现细节。 此外,无论是已在线业务进行防篡改改造,还是新上线业务使用防篡改功能,SphereEx-DBPlusEngine 都可以提供一套相对完善的解决方案。

防篡改模块将用户发起的 SQL 进行拦截,并通过 SQL 语法解析器进行解析、理解 SQL 行为,再依据用户传入的防篡改规则,找出需要进行防篡改的字段和所使用的防篡改算法对目标字段进行加防篡改摘要处理后,再与底层数据库进行交互。SphereEx-DBPlusEngine 会将用户请求的数据和进行防篡改摘要后的数据存储到底层数据库;通过屏蔽对数据的防篡改处理,使用户无需感知解析 SQL、数据防篡改等过程,提升用户使用体验。

举例说明,假如数据库里有一张表叫做 t_user,这张表里实际有两个字段 email,用于存放邮箱数据、password,用于存放用户密码数据。同时 emailpassword 没有配置加密规则,对应的逻辑列也分别为 emailpassword。 那么,用户在编写 SQL 时应该面向 logicColumn 进行编写,即 INSERT INTO t_user SET password = '123', email='1@1'。SphereEx-DBPlusEngine 接收到该 SQL,通过用户提供的防篡改配置,发现 emailpassword 组合配置了防篡改摘要列 digest_email_password,于是便会获取 SQL 里指定的emailpassword 值,通过指定的摘要算法计算得到最终的摘要值,假设此处最终得到的摘要值为 digest_1@1_123。最终 SphereEx-DBPlusEngine 会将逻辑 SQL 进行改写,得到最终的真实 SQL:INSERT INTO t_user SET password = '123', email='1@1', digest_email_password= 'digest_1@1_123' 下发到底层存储数据库上执行。

防篡改算法解析 #

SphereEx-DBPlusEngine 提供的防篡改摘要算法接口为 MessageDigestAlgorithm。 一方面,SphereEx-DBPlusEngine 为用户提供了丰富的内置防篡改摘要实现类,用户只需进行配置即可使用; 另一方面,为了满足用户不同场景的需求,我们还开放了相关防篡改摘要接口,用户可依据接口提供具体自定义实现类。

  • MessageDigestAlgorithm 通过提供 digest() 方法对需要防篡改的数据进行防篡改摘要。 在用户进行 INSERT, UPDATE时,SphereEx-DBPlusEngine 会按照用户配置,对SQL进行解析、改写、路由,并调用 digest() 将数据防篡改摘要后存储到数据库, 而在 SELECT 时,则会屏蔽不会直接返回真实的防篡改信息。 当前,SphereEx-DBPlusEngine 针对这种类型的防篡改解决方案提供了如下具体实现类,分别是 MD5(不可逆),SHA(不可逆),SM3(不可逆)和 HMAC(不可逆),用户只需配置即可使用这几种内置的方案。

防篡改配置 #

防篡改配置元素分为两大部分:防篡改摘要算法配置和防篡改表配置,如下:

摘要算法配置:指使用什么摘要算法进行防篡改摘要。目前 SphereEx-DBPlusEngine 内置了五种加解密算法:MD5(不可逆),SHA(不可逆),SM3(不可逆)和 HMAC(不可逆)。

防篡改表配置:用于告诉 SphereEx-DBPlusEngine 数据表里允许同时配置多组摘要配置,进行防篡改操作(digestGroups)。其中每一组摘要配置,需要告知使用什么算法进行防篡改(digesterName)、哪些逻辑列进行防篡改(columns),最后防篡改摘要后的数据存储在哪个列里(digestColumnName)。

使用指南 #

防篡改-新上线业务 #

新上线业务由于一切从零开始,不存在历史数据清洗问题,所以相对简单。选择合适的防篡改算法,如 SM3 后,只需配置逻辑列(面向用户编写 SQL )和防篡改列(数据表存防篡改数据)即可。建议配置如下(YAML 格式展示):

- !DATA_INTEGRITY
  digesters:
    sm3_digester:
      type: SM3
      props:
        sm3-salt: 12345678
  tables:
    t_user:
      digestGroups:
        - { columns: [ user_name ], digesterName: sm3_digester, digestColumnName: digest_user_name }
        - { columns: [ password, email ], digesterName: sm3_digester, digestColumnName: digest_password_email }

使用这套配置,SphereEx-DBPlusEngine 只需将 digestGroups 里每一组配置的逻辑列进行摘要处理,将摘要后的摘要值存储到对应的摘要列里即可。

  1. 设计防篡改表,确定防篡改字段,可结合表结构、数据特点及应用情况综合考虑;
  2. 在 SphereEx-DBPlusEngine 创建逻辑库,注册存储节点(空);
  3. 创建防篡改规则,可使用 SphereEx-Console 或 DistSQL 完成;
  4. 创建防篡改表,完成防篡改表构建;
  5. 根据业务实际情况,再选择保留或删除明文字段。

防篡改-洗数-已上线业务改造 #

对于已上线的业务,需评估改造后 SQL 的支持度,另外存量数据洗数是必不可少的一个环节。

支持的洗数类型如下:

  • 按表洗数:初次洗数的表,所有防篡改列可以一次性完成洗数
  • 按列洗数:表执行过洗数之后,额外给其它某些列洗数
  1. 确认防篡改范围 根据合规需求,明确具体的防篡改数据范围。

  2. 确认防篡改算法 选择并确认适合的防篡改算法。

  3. 洗数 完成以上内容后,对于已上线的项目,需要对存量数据进行洗数。该过程无需引用外部组件,SphereEx-DBPlusEngine 可完成洗数过程,该过程可在线进行。

  4. 启用防篡改列 启用防篡改列之后,应用的请求将通过 SphereEx-DBPlusEngine 与防篡改列字段产生交互。

防篡改-重洗数 #

  1. 启动自动换密钥流程

  2. 执行重洗数第二阶段

  3. 提交重洗数作业

防篡改校验函数 DATA_INTEGRITY_CHECK #

为了方便用户查看数据库中存储的数据是否被篡改,DBPlusEngine 提供了 DATA_INTEGRITY_CHECK 函数,用于校验逻辑列是否被篡改,该函数和数据库的标准函数使用方法相同,具体如下:

新增 DATA_INTEGRITY_CHECK(columnName...) 函数,校验一张表里的指定列是否被篡改。

函数定义 #

该函数的入参定义如下:

  1. columnName 必须为防篡改规则里配置的防篡改列;
  2. 如果防篡改列规则一组里指定了多个列,必须同时指定该组的所有列,列的顺序任意;
  3. 可以通过 DATA_INTEGRITY_CHECK(*) 方式,校验一张表的所有防篡改规则,一旦有任意一列被篡改,则返回 FALSE。

该函数的返回值如下:

  1. 如果 CHECK 通过(未被篡改),则返回 TURE;
  2. 如果 CHECK 未通过(被篡改),则返回 FALSE。

使用限制 #

当使用 DATA_INTEGRITY_CHECK 函数时,对于以下不支持的语法,会进行 SQL 语法校验并提示。

查询语法限制:

  1. 仅支持简单查询语法。
  2. 不支持子查询、关联查询;
  3. 不支持 Group By
  4. 不支持指定多张表;
  5. 不支持 UnionUnion ALL

使用示例 #

对于如下的防篡改规则配置,下面提供了一些的防篡改校验函数的使用示例。

- !DATA_INTEGRITY
  digesters:
    sm3_digester:
      type: SM3
      props:
        sm3-salt: 12345678
      sm3_digester:
        type: SM3
  tables:
    t_user:
      digestGroups:
        - { columns: [ user_name ], digesterName: sm3_digester, digestColumnName: digest_user_name }
        - { columns: [ password, email ], digesterName: sm3_digester, digestColumnName: digest_password_email }

防篡改校验函数 DATA_INTEGRITY_CHECK 的使用示例如下:

-- 校验一张表的 USER_NAME 列是否被篡改
SELECT user_id, DATA_INTEGRITY_CHECK(USER_NAME) FROM t_user;

-- PASSWORD 和 EMAIL 是一组防篡改配置里的防篡改列,在使用函数时必须同时指定,顺序可以任意
SELECT user_id, DATA_INTEGRITY_CHECK(PASSWORD, EMAIL) FROM t_user WHERE user_id > 10;

-- 可以在一条 SQL 里使用多次 DATA_INTEGRITY_CHECK 函数
SELECT DATA_INTEGRITY_CHECK(USER_NAME), user_id, DATA_INTEGRITY_CHECK(password, email), DATA_INTEGRITY_CHECK(EMAIL, PASSWORD) FROM t_user WHERE user_id > 10;

-- 可以通过别名给 DATA_INTEGRITY_CHECK 函数指定别名
-- MySQL 指定别名方式如下
SELECT DATA_INTEGRITY_CHECK(USER_NAME) AS `USER_CHECK`, user_id, DATA_INTEGRITY_CHECK(password, email) AS `PASSWORD_EMAIL_CHECK` FROM t_user WHERE user_id > 10;
-- PostgreSQL/openGauss/DM/Oracle 指定别名的方式如下
SELECT DATA_INTEGRITY_CHECK(USER_NAME) AS  "USER_CHECK", user_id FROM t_user WHERE user_id > 10;

-- 可以通过 DATA_INTEGRITY_CHECK(*) 校验一张表里的所有防篡改列
SELECT USER_NAME, DATA_INTEGRITY_CHECK(*), USER_ID FROM t_user WHERE user_id > 10;

操作指南 #

具体操作 DBPlusEngine 进行数据防篡改时,需要按照如下的操作步骤进行。

数据防篡改-新业务 #

  1. 梳理业务逻辑,评估系统中需要进行数据防篡改的表和列信息,可结合表结构、数据特点及应用情况综合考虑;

  2. 在 SphereEx-DBPlusEngine 创建逻辑库,注册存储节点(空);

  3. 创建防篡改规则,可使用 SphereEx-Console 或 DistSQL 完成;

  4. 创建防篡改表,完成防篡改表构建;

  5. 进行防篡改操作验证。

防篡改洗数-成熟业务 #

  1. 设计防篡改表,确定防篡改字段,可结合表结构、数据特点及应用情况综合考虑;

  2. 在 SphereEx-DBPlusEngine 创建逻辑库,注册数据源;

  3. 使用 DistSQL 创建防篡改规则;

  4. 通过 INTEGRATE TABLE 命令开始防篡改洗数;

  5. 防篡改洗数完成业务进行业务操作,SphereEx-DBPlusEngine 会自动计算防篡改摘要值存储到数据库中。

配置示例 #

以最常用的加密场景,在原有加密基础上,对加密列进行防篡改配置的示例如下: 假设原有系统中,有一张 t_user 表进行了加密配置。对 t_user 里的 user_namepasswordemail 分别进行了加密配置。具体配置如下:

1. YAML 配置 #

- !ENCRYPT
# ......
tables:
  t_user:
  columns:
    user_name:
      cipher:
        name: user_name_cipher
        encryptorName: aes_encryptor
    password:
      cipher:
        name: password_cipher
        encryptorName: aes_encryptor
    email:
      cipher:
        name: email_cipher
        encryptorName: aes_encryptor

现在要在原有加密配置基础上,对加密列进行防篡改配置。 准备在原有的逻辑表 t_user 上配置多个防篡改摘要组(digestGroups)。 第一组对原有的逻辑列 user_name 使用 sm3_digester 摘要算法,将摘要结果配置存储到 digest_user_name 列上。 第二组对原有的逻辑列 passwordemail 上,使用 sm3_digester 摘要算法,将摘要结果配置存储到 digest_password_email 列上。 配置示例如下:

- !DATA_INTEGRITY
  digesters:
    sm3_digester:
      type: SM3
      props:
        sm3-salt: 12345678
      sm3_digester:
        type: SM3
  tables:
    t_user:
      digestGroups:
        - { columns: [ user_name ], digesterName: sm3_digester, digestColumnName: digest_user_name }
        - { columns: [ password, email ], digesterName: sm3_digester, digestColumnName: digest_password_email }

2. DistSQL 配置 #

使用 DistSQL 进行如上操作的流程如下:

背景:假设原有系统已经配置了加密规则,并且表里已经存在加密的存量数据。

-- 查询现有的加密配置
mysql> show encrypt rules;
+--------+--------------+-----------------+-----------------------+------------------+----------------------+-----------------+-----------------------+--------------------------+---------------------+----------------------+--------------------+-----------------------+----------------+---------------------------------------------------------------+---------------------+----------------------+------------------------------+-------------------------------------+------------------+-------------------+------------------+
| table  | logic_column | logic_data_type | cipher_column         | cipher_data_type | plain_column         | plain_data_type | assisted_query_column | assisted_query_data_type | like_query_column   | like_query_data_type | order_query_column | order_query_data_type | encryptor_type | encryptor_props                                               | assisted_query_type | assisted_query_props | like_query_type              | like_query_props                    | order_query_type | order_query_props | query_with_plain |
+--------+--------------+-----------------+-----------------------+------------------+----------------------+-----------------+-----------------------+--------------------------+---------------------+----------------------+--------------------+-----------------------+----------------+---------------------------------------------------------------+---------------------+----------------------+------------------------------+-------------------------------------+------------------+-------------------+------------------+
| t_user | user_name    |                 | user_name_cipher      |                  | user_name_plain      |                 |                       |                          | user_name_like      |                      |                    |                       | AES            | {"aes-key-value":"123456abc","digest-algorithm-name":"SHA-1"} |                     |                      | SphereEx:CHAR_TRANSFORM_LIKE | {"key-manager":"local-key-manager"} |                  |                   | false            |
| t_user | password     |                 | password_cipher       |                  |                      |                 |                       |                          |                     |                      |                    |                       | AES            | {"aes-key-value":"123456abc","digest-algorithm-name":"SHA-1"} |                     |                      |                              |                                     |                  |                   | false            |
| t_user | email        |                 | email_cipher          |                  |                      |                 |                       |                          |                     |                      |                    |                       | AES            | {"aes-key-value":"123456abc","digest-algorithm-name":"SHA-1"} |                     |                      |                              |                                     |                  |                   | false            |
| t_user | telephone    |                 | user_telephone_cipher |                  | user_telephone_plain |                 |                       |                          | user_telephone_like |                      |                    |                       | AES            | {"aes-key-value":"123456abc","digest-algorithm-name":"SHA-1"} |                     |                      | SphereEx:CHAR_TRANSFORM_LIKE | {"key-manager":"local-key-manager"} |                  |                   | false            |
+--------+--------------+-----------------+-----------------------+------------------+----------------------+-----------------+-----------------------+--------------------------+---------------------+----------------------+--------------------+-----------------------+----------------+---------------------------------------------------------------+---------------------+----------------------+------------------------------+-------------------------------------+------------------+-------------------+------------------+
4 rows in set (1.18 sec)
  1. 通过 convert table 语句,将原有的加密表增加防篡改配置,并完成数据防篡改洗数。
CONVERT TABLE `t_user` BY DATA_INTEGRITY RULE (
  (DIGEST_COLUMN=`digest_user_name`, DATA_TYPE="varchar(50)", COLUMNS(`user_name`), TYPE(NAME='MD5', PROPERTIES('salt'='123456'))),
  (DIGEST_COLUMN=`digest_password_email`, DATA_TYPE="varchar(50)", COLUMNS(`password`, `email`), TYPE(NAME='MD5', PROPERTIES('salt'='123456')))
), start_job=true;
  1. 验证防篡改规则创建成功
mysql> show data_integrity rules;
+--------+-----------------------+----------------+-------------+-------------------+
| table  | digest_column         | columns        | digest_type | digest_props      |
+--------+-----------------------+----------------+-------------+-------------------+
| t_user | digest_user_name      | user_name      | MD5         | {"salt":"123456"} |
| t_user | digest_password_email | password,email | MD5         | {"salt":"123456"} |
+--------+-----------------------+----------------+-------------+-------------------+
2 rows in set (0.00 sec)
  1. 进行数据插入和更新操作。
-- 执行插入操作,会自动进行数据防篡改改写操作。
mysql> insert into t_user values(20, 'spex', '123', '1@abc.com', '15111111111', '2024-01-01 11:11:11');
Query OK, 1 row affected (0.01 sec)

-- 可以通过 preview 查看改写生成的真实 SQL 语句。其中 digest_user_name 和 digest_password_email 为防篡改列。
mysql> preview insert into t_user values(20, 'spex', '123', '1@abc.com', '15111111111', '2024-01-01 11:11:11');
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| data_source_name | actual_sql                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| encrypt          | insert into `demo_data_integrity`.t_user(user_id, user_name_cipher, user_name_like, user_name_plain, digest_user_name, password_cipher, digest_password_email, email_cipher, user_telephone_cipher, user_telephone_like, user_telephone_plain, creation_date) values(20, 'hwZKkl70Yoohy0rorXn1qA==', 'IJeB', 'spex', '5c74b8d306482669fce60cb2c6fdcf73', 'DZEHT99l6UjthceKuCCKIw==', 'faf9aa646d8860bd02dc6194b029f813', 'V4BYnLqOS2ESp9YIrHhffA==', 'tRpk2BaQpHuLevQwpMLsFQ==', ',(,,,,,,,,,', '15111111111', '2024-01-01 11:11:11') |
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.26 sec)
-- 执行更新操作,会自动进行数据防篡改改写操作。
mysql> update t_user set user_name = 'test' where user_id = 20;
Query OK, 1 row affected (0.06 sec)

-- 可以通过 preview 查看改写生成的真实 SQL 语句。
mysql> preview update t_user set user_name = 'test' where user_id = 20;
+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| data_source_name | actual_sql                                                                                                                                                                                                         |
+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| encrypt          | update `demo_data_integrity`.t_user set user_name_cipher = 'd3aNbnZpr4euQa0WGuMElA==', user_name_like = 'NeIN', user_name_plain = 'test', digest_user_name = '47ec2dd791e31e2ef2076caf64ed9b3d' where user_id = 20 |
+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
  1. 检查数据是否被篡改
-- 开启防篡改校验任务
mysql> CHECK DATA_INTEGRITY TABLE t_user BY TYPE (
  NAME = 'OUTPUT:DATABASE',
  PROPERTIES (
    'diff-storage-unit-name' = 'encrypt',
    'diff-table-name' = 'diff'
  )
);
-- 查看防篡改校验任务
mysql> SHOW DATA_INTEGRATING CHECK LIST
-- 查看防篡改校验任务状态
mysql> SHOW DATA_INTEGRATING CHECK STATUS jobId
-- 查询防篡改校验结果
mysql> SELECT * FROM diff;