数据库高安全—数据保护:数据动态脱敏

书接上文数据库高安全—审计追踪:传统审计&统一审计,从传统审计统一审计两方面对高斯数据库的审计追踪技术进行解读,本篇将从数据动态脱敏方面对高斯数据库的数据保护技术进行解读。

5.1 数据动态脱敏

数据脱敏,顾名思义就是将敏感数据通过变形、屏蔽等方式处理,其目的是保护隐私数据信息,防止数据泄露和恶意窥探。当企业或者机构收集用户个人身份数据、手机、银行卡号等敏感信息,然后将数据通过导出(非生产环境)或直接查询(结合生产环境)的方式投入使用时,按照隐私保护相关法律法规需将数据进行“脱敏”处理。

openGauss实现了数据动态脱敏机制,它根据一系列用户配置的“脱敏策略”来对查询命令进行分析匹配,最终将敏感数据屏蔽并返回。使用数据动态脱敏特性总的来说分为两个步骤:配置脱敏策略、触发脱敏策略。本小节将对这两个步骤进行具体分析。

显然,只有在配置脱敏策略后系统才能有根据地进行敏感数据脱敏。openGauss提供了脱敏策略配置(创建、修改、删除)语法,这些语法所涉及的语法解析结点内容大致相同,因此这里仅对创建策略相关数据结构进行分析,其余不再赘述。下面将结合一个具体示例对数据动态脱敏特性进行详细介绍。

表1给出了一张包含敏感信息(薪资、银行卡号)的个人信息表,策略管理员要对该表中的敏感信息创建脱敏策略:当用户user1或user2在IP地址10.123.123.123上使用jdbc或gsql连接数据库并查询个人信息表时,系统将自动屏蔽敏感信息。

表1  个人信息表person

id

name

gender

salary

creditcards

1

张三

10000

6210630600006321083

2

李四

15000

6015431250003215514

3

王五

20000

5021134522201529881

首先策略管理员需要对敏感列打标签,随后使用标签创建脱敏策略,策略配置DDL语句如下:

例1脱敏策略配置示例。

配置资源标签:

    CREATE RESOURCE LABEL salary_label ADD COLUMN(person.salary);CREATE RESOURCE LABEL creditcard_label ADD COLUMN(person.creditcards);

    配置脱敏策略:

      CREATE MASKING POLICY mask_person_policy MASKALL ON LABEL(salary_label), CREDITCARDMASKING ON label(creditcard_label) FILTER ON ROLES(user1,user2), IP(‘10.123.123.123’), APP(jdbc, gsql);

      user1在10.123.123.123地址使用gsql查询敏感数据:

        SELECT id, salary, creditcards from public.person;

        下面将对CREATE MASKING POLICY语句所涉及的语法结构定义进行逐一介绍。

        数据结构CreateMaskingPolicyStmt:

          typedef struct CreateMaskingPolicyStmt{NodeTag     type;char        *policy_name;    // 脱敏策略名称List        *policy_data;    // 脱敏策略行为List        *policy_filters; // 用户过滤条件bool        policy_enabled;  // 策略开关} CreateMaskingPolicyStmt;

          脱敏策略创建语法是对CreateMaskingPolicyStmt进行填充,其中policy_data是由若干DefElem节点组成的List,每个DefElem指出了以何种方式脱敏数据库资源,DefElem->name标识脱敏方法,DefElem->arg代表脱敏对象。

          数据动态脱敏中例1脱敏策略配置示例的步骤(3) 对应的policy_data组织结构如图1所示。

          图片

          图1 脱敏策略配置示例对应的policy_data组织结构

          policy_filters描述了脱敏策略生效的用户场景(用户名、客户端、登录IP),该List只有一个节点,是Policy Filter前缀逻辑树的根节点,只有当用户信息满足逻辑树所描述的场景时,其相应的脱敏策略才会生效。Policy Filter逻辑树节点如下所示:

            typedef struct PolicyFilterNode{NodeTag     type;char        *node_type;  // 逻辑操作类型,取值为“op”或“filter”char        *op_value;   // 逻辑操作符,仅当node_type为op时取值为“and”或“or”,否则为NULLchar        *filter_type;// 过滤数据类型,仅当node_type为filter时取值为“APP”、“ROLES”、“IP”List        *values;     // 过滤数据值List,指出具体的过滤条件值,若node_type为op时置NULLNode        *left;       // 左子树Node        *right;      // 右子树} PolicyFilterNode;

            逻辑树节点分为操作符(op)节点和过滤数据(filter)节点,当op节点分为“与”或“或”关系,其op_value将置为“and”或“or”,其左右子树代表操作符左右子表达式。filter节点一般作为op的叶子节点出现,它标识具体的过滤信息并将其值存放在values链表中。需要注意的是,一个节点不可能既是op节点又是filter节点。数据动态脱敏中例1脱敏策略配置示例的步骤(3) 对应的policy_filters组织结构如图2所示。

            图片

            图2 配置脱敏策略对应的policy_filter组织结构

            脱敏策略配置的总体流程如图3所示。

            图片

            图3 脱敏策略配置流程图

            在查询编译脱敏策略配置SQL之后将进入策略增删改主函数中,首先会根据语法解析节点校验相关参数的合法性,做如下检查:

            • 检查脱敏策略指定的数据库资源是否存在。

            • 检查脱敏函数是否存在。

            • 检查脱敏策略是否已存在。

            • 检查脱敏相关约束:脱敏对象必须为基本表的数据列、脱敏列类型必须满足规格限制、脱敏列只允许加载一个脱敏函数。

            • 检查Masking Filter是否冲突,不允许同一数据库资源在相同用户场景下触发多个策略。

            其中Masking Filter冲突校验的目的是为了防止用户场景同时满足多个脱敏策略限制,导致策略匹配时系统无法判断应该触发哪种脱敏策略。因此在创建策略时要保证其Filter与现存的策略互斥,主要是判断是否存在一种用户场景能够同时满足多个MASKING FILTER。在数据动态脱敏所示的表2数据基础上,如下表中策略A和策略B是相互冲突的,而策略A和策略C是互斥的。

            脱敏策略冲突或互斥场景:

              策略A:CREATE MASKING POLICY mask_A MASKALL ON LABEL(creditcard_label) FILTER ON IP(’10.123.123.123’), APP(jdbc), ROLES(user1);策略B:CREATE MASKING POLICY mask_B CREDITCARDMASKING ON LABEL(creditcard_label) FILTER ON IP(’10.123.123.123’,’10.90.132.132’), APP(jdbc, gsql), ROLES(user1);策略C:CREATE MASKING POLICY mask_C CREDITCARDMASKING ON LABEL(creditcard_label) FILTER ON IP(’10.123.123.123’ ,’10.90.132.132’), APP(jdbc), ROLES(user2);

              随后将依据策略配置信息更新系统表:

              • 更新gs_masking_policy系统表,存储policy基本信息。

              • 更新gs_masking_policy_actions系统表,存储策略对应的脱敏方式及脱敏对象。

              • 更新gs_masking_policy_filter系统表,存储脱敏用户场景过滤信息,此时会将逻辑树转换为逻辑表达式字符串进行存储,在之后的敏感数据访问时该字符串将会重新转换为逻辑树进行场景校验。

              为了降低策略读取IO损耗,openGauss维护了一组线程级别的策略缓存,用于保存已配置的脱敏策略,并在策略配置后进行实时刷新。

              在用户进行数据查询时,数据动态脱敏特性使用openGauss的HOOK机制,将查询编译生成的查询树(Query)钩取出来与脱敏策略进行匹配,最后将查询树按照脱敏策略内容改写成不包含敏感数据的“脱敏”查询树返还给解析层继续执行,最终实现屏蔽敏感数据的能力。其执行流程图如4所示。

              图片

              图4 脱敏策略执行流程图

              在对一个访问数据库资源的查询树进行脱敏之前,需要准备一份待匹配的脱敏策略集合,其依据就是用户登录信息,check_masking_policy_filter函数的任务就是将用户信息与所有的脱敏策略进行匹配,筛选出可能被查询触发的脱敏策略。最终筛选如下脱敏策略:

              • 若脱敏策略没有配置FILTER信息,说明对所有用户生效。

              • 若当前用户信息与脱敏策略的FILTER匹配,则说明对当前用户生效。

              在每个脱敏策略从系统表读入缓存时,需要将对应的FILTER逻辑表达式转换为逻辑树并将逻辑树根节点存入缓存中,将其作为脱敏策略筛选条件,逻辑树结构如下。

                class PolicyLogicalTree {public:    bool parse_logical_expression(const gs_stl::gs_string logical_expr_str);   // 逻辑表达式构造逻辑树入口函数    bool match(const FilterData *filter_item);    bool has_intersect(PolicyLogicalTree *arg);private:    gs_stl::gs_vector<PolicyLogicalNode> m_nodes;  // 逻辑节点集合,包含了逻辑树中所有的节点    gs_stl::gs_vector<int> m_flat_tree;   // 利用数组将逻辑节点索引构造逻辑二叉树    // 逻辑表达式转换为逻辑树的递归函数。bool parse_logical_expression_impl(const gs_stl::gs_string logical_expr_str, int *offset, int *idx, Edirection direction);     inline void create_node(int *idx, EnodeType type, bool has_operator_not); // 创建单个逻辑树节点    void flatten_tree();  // 将逻辑树刷新到m_nodes集合与m_flat_tree索引中    bool check_apps_intersect(string_sort_vector*, string_sort_vector*);    bool check_roles_intersect(oid_sort_vector*, oid_sort_vector*);    bool m_has_ip;    // 标识整个逻辑树是否涉及ip校验    bool m_has_role;  // 标识整个逻辑树是否涉及用户名校验    bool m_has_app;   // 标识整个逻辑树是否涉及客户端校验};

                逻辑树节点的结构与语法解析中的FILTER节点类似,具体可以参照PolicyFilterNode结构。

                  struct PolicyLogicalNode {    ...EnodeType m_type;int m_left;                // 左子节点索引int m_right;               // 右子节点索引void make_eval(const FilterData *filter_item); //判断用户信息是否满足本节点子树表示的逻辑。bool m_eval_res;oid_sort_vector m_roles;   // 本节点包含的用户名集合string_sort_vector m_apps; // 本节点包含的客户端名称集合IPRange m_ip_range;        //本节点包含的IP};

                  当需要将逻辑表达式转变为逻辑树时,parse_logical_expression_impl函数将对逻辑表达式字符串进行递归解析,识别出表达式包含的操作符(and或or)以及Filter信息(ip、roles、app),构造出PolicyLogicalNode并使用左右子节点索引(m_left、m_right)链接起来形成逻辑树并将每个节点存入m_nodes中,最终利用m_nodes构造m_flat_tree数组来模拟二叉树。

                  m_flat_tree数组的作用是标记逻辑树节点间关系以及标识哪些节点是逻辑树的叶子节点,当用户信息与逻辑树某节点进行匹配时,首先需要与其左右子树进行匹配,然后根据该节点的逻辑运算符来判断是否满足Filter要求,而左右子树的判断结果又依赖于它们的子树的结果,因此这种递归判断方法首先将会是取叶子节点进行用户信息匹配。

                  openGauss使用“自底向上”的方式来进行用于信息与逻辑树的匹配,从m_flat_tree末尾即叶子节点进行匹配,将匹配结果记录下来,当匹配到非叶子节点时(op节点)只需使用其左右子节点结果进行判断即可,最终实现整个逻辑树的匹配。在例1脱敏策略配置示例中创建脱敏策略后,当用户使用非受限的客户端访问敏感数据时,逻辑树匹配结果如图5所示。

                  图片

                  图5 逻辑树匹配示例

                  在筛选出脱敏策略后,就需要对查询树所有TargetEntry进行识别和策略匹配,从openGauss源码可以看到,支持对SubLink、Aggref、OpExpr、RelabelType、FuncExpr、CoerceViaIO、Var类型的节点进行解析识别。数据脱敏的核心思路是,Var类型节点代表了访问的数据库资源,而非Var类型节点可能包含Var节点,因此需要根据其参数递归的寻找Var节点,最后将识别到的所有Var节点进行策略匹配并根据策略内容进行节点替换。

                  识别脱敏结点源码:

                    static bool mask_expr_node(ParseState *pstate, Expr*& expr,    const policy_set *policy_ids, masking_result *result, List* rtable, bool can_mask){    if (expr == NULL) {        return false;    }    switch (nodeTag(expr)) {        case T_SubLink:            ... // 解析SubLink结点        case T_FuncExpr:            ... // 解析FuncExpr结点        case T_Var:            return handle_masking_node(pstate, expr, policy_ids, result, rtable, can_mask); // 进入最后脱敏处理过程        break;        case T_RelabelType:            ... // 解析RelabelType结点        case T_CoerceViaIO:            ... // 解析CoerceViaIO结点        case T_Aggref:            ... // 解析Aggref结点        case T_OpExpr:            ... // 解析OpExpr结点        default:            break;    }    return false;}

                    在匹配脱敏策略时,首先需要将识别出的Var节点进行解析,将其转为PolicyLabelItem,该数据结构存储了数据列的全部路径信息,然后将其与已过滤出的脱敏策略集合进行匹配,若某个脱敏策略对应的数据库资源对象与PolicyLabelItem一致,将已匹配到的脱敏策略指定的方式替换该Var节点,相关数据结构如下:数据结构PolicyLabelItem。

                      struct PolicyLabelItem {    ...    void get_fqdn_value(gs_stl::gs_string *value) const;
                          bool operator < (const PolicyLabelItem& arg) const;    bool operator == (const PolicyLabelItem& arg) const;    bool empty() const {return strlen(m_column) == 0;}    void set_object(const char *obj, int obj_type = 0);    void set_object(Oid objid, int obj_type = 0);    Oid            m_schema;     // 数据库资源所属的namespace Oid    Oid            m_object;     // 数据库资源所属的table Oid    char           m_column[256];// 列名    int            m_obj_type;   // 资源类型,数据动态脱敏仅支持对COLUMN生效};

                      脱敏策略匹配成功后,将会根据策略内容替换包含敏感信息的Var节点,使之外嵌脱敏函数。最后将修改后的查询树返还给解析器继续执行,最终敏感数据将会在脱敏函数的作用下返回,以脱敏的形式返回给客户端。数据动态脱敏中例1脱敏策略配置示例里使用gsql查询敏感数据的步骤(4) 中SELECT语句对应的查询树脱敏前的数据组织结构如图6所示。

                      图片

                      图6 脱敏结点替换示例

                      至此,整个查询树已经完成了脱敏策略的匹配与重写,随后将重新回归查询解析模块并继续执行后续处理,最终系统将返回脱敏后的数据结果。

                      以上内容从数据动态脱敏方面对高斯数据库的数据保护技术进行了解读,下篇讲从数据透明加密方面继续介绍高斯数据库的数据保护。

                      本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15550.html

                      如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

                      相关文章

                      《艾尔登法环》运行时弹窗“由于找不到vcruntime140.dll,无法继续执行代码”要怎么解决?

                      宝子们&#xff0c;是不是在玩《艾尔登法环》的时候&#xff0c;突然弹出一个提示&#xff1a;“由于找不到vcruntime140.dll&#xff0c;无法继续执行代码”&#xff1f;这可真是让人着急上火&#xff01;别慌&#xff0c;今天就给大家唠唠这个文件为啥会丢&#xff0c;还有怎…

                      【Git】Failed to connect to github.com port 443: Timed out

                      由于DNS污染国内访问github经常会超时&#xff0c;参考网上的方法修改host文件绑定ip过段时间就失效了&#xff0c;这里介绍一个修改工具&#xff0c;通过修改本地host来绕过国内DNS解析实现连接 UsbEAm Hosts Editor UsbEAm Hosts Editor [多平台hosts修改] V3.63 – Dogfigh…

                      qml RoundButton详解

                      1、概述 RoundButton是QML&#xff08;Qt Modeling Language&#xff09;中的一种按钮控件&#xff0c;它继承自Button控件&#xff0c;并增加了一个特殊的属性——radius&#xff0c;用于设置按钮圆角的半径。这使得RoundButton能够呈现为带有圆角的形状&#xff0c;而不仅仅…

                      Django在终端创建项目(pycharm Windows)

                      1.选择目录 选择或新建一个文件夹&#xff0c;作为项目保存的地方 2.右键在终端打开 3.确定django-admin.exe安装位置 找到自己安装django时&#xff0c;django-admin.exe安装的位置&#xff0c;例如 4.运行命令 使用django-admin.exe的绝对路径&#xff0c;在刚才打开的终端…

                      Visual Studio 2022 中使用 Google Test

                      要在 Visual Studio 2022 中使用 Google Test (gtest)&#xff0c;可以按照以下步骤进行&#xff1a; 安装 Google Test&#xff1a;确保你已经安装了 Google Test。如果没有安装&#xff0c;可以通过 Visual Studio Installer 安装。在安装程序中&#xff0c;找到并选择 Googl…

                      Unity-Mirror网络框架-从入门到精通之LagCompensation示例

                      文章目录 前言什么是滞后补偿Lag Compensation示例延迟补偿原理ServerCubeClientCubeCapture2DSnapshot3D补充LagCompensation.cs 独立算法滞后补偿器组件注意:算法最小示例前言 在现代游戏开发中,网络功能日益成为提升游戏体验的关键组成部分。本系列文章将为读者提供对Mir…

                      数据集成实例分享:金蝶云星空对接旺店通实现库存管理自动化

                      拆卸父项出库&#xff1a;金蝶云星空数据集成到旺店通企业奇门 在现代企业的运营过程中&#xff0c;数据的高效流动和准确处理至关重要。本文将分享一个实际案例&#xff0c;展示如何通过轻易云数据集成平台&#xff0c;将金蝶云星空的数据无缝对接到旺店通企业奇门&#xff0…

                      Git、Github和Gitee完整讲解:丛基础到进阶功能

                      第一部分&#xff1a;Git 是什么&#xff1f; 比喻&#xff1a;Git就像是一本“时光机日记本” 每一段代码的改动&#xff0c;Git都会帮你记录下来&#xff0c;像是在写日记。如果出现问题或者想查看之前的版本&#xff0c;Git可以带你“穿越回过去”&#xff0c;找到任意时间…

                      解锁 DeepSeek 模型高效部署密码:蓝耘平台深度剖析与实战应用

                      &#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

                      autMan奥特曼机器人-对接deepseek教程

                      一、安装插件ChatGPT 符合openai api协议的大模型均可使用此插件&#xff0c;包括chatgpt-4/chatgpt-3.5-turbo&#xff0c;可自定义服务地址和模型&#xff0c;指令&#xff1a;gpt&#xff0c;要求Python3.7以上&#xff0c;使用官方库https://github.com/openai/openai-pyt…

                      循环神经网络学习01——transformer:输入部分-嵌入层位置编码

                      一、介绍 1、核心思想 利用自注意力机制来捕获输入序列中各元素之间的全局依赖关系&#xff0c;无论这些元素之间的实际距离有多远。 自注意力机制&#xff1a;允许模型在处理序列的每个元素时&#xff0c;考虑到序列中的所有其他元素&#xff0c;从而捕捉它们之间的关系和依…

                      git rebase 和 git merge的区别

                      Rebase 可使提交树变得很干净, 所有的提交都在一条线上。 Merge 则是包含所有的调试记录&#xff0c;合并之后&#xff0c;父级的所有信息都会合并在一起 Rebase 修改了提交树的历史 比如, 提交 C1 可以被 rebase 到 C3 之后。这看起来 C1 中的工作是在 C3 之后进行的&#xf…

                      上马传奇新手起号攻略 上马传奇云手机开荒玩法

                      在上马传奇这款游戏中&#xff0c;我们可以选择合适的职业&#xff0c;参与各类玩法快速起号&#xff0c;今天就给大家一些攻略。 一、职业 1.游戏中的战士、法师、道士分别有三个分支&#xff0c;一共九个职业可以选择&#xff0c;选择之后不能转职&#xff0c;所以前期要慎重…

                      Redis 集群(Cluster)和基础的操作 部署实操篇

                      三主三从 集群概念 Redis 的哨兵模式&#xff0c;提高了系统的可用性&#xff0c;但是正在用来存储数据的还是 master 和 slave 节点&#xff0c;所有的数据都需要存储在单个 master 和 salve 节点中。 如果数据量很大&#xff0c;接近超出了 master / slave 所在机器的物理内…

                      【JavaScript】this 指向由入门到精通

                      this 的概念 this 在JavaScript 及其其他面向对象的编程语言中&#xff0c;存在的目的是为了提供一种在对象方法中引用当前对象的方式。 它为方法提供了对当前实例的引用&#xff0c;使得方法能够访问或者修改实例的成员变量。 注意点&#xff1a; this 的绑定和定位的位置…

                      C++ STL容器之vector的使用及复现

                      vector 1. 序列式容器 vector、list、deque、forward_list(C11)等STL容器&#xff0c;其底层为线性序列的数据结构&#xff0c;里面存储的是元素本身&#xff0c;这样的容器被统称为序列式容器。 2. vector容器 vector使用模板作为参数&#xff0c;所以在使用的时候必须将模…

                      算法15(力扣347)——前k个高频元素

                      1、问题 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 2、示例 &#xff08;1&#xff09; 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2] &#xff08;2&#xff09; 输入: nums [1], k 1 输出: [1…

                      项目质量管理体系及保证措施

                      项目质量管理体系的核心是建立标准化流程、强化全员参与意识、实施动态监控机制。其中&#xff0c;标准化流程是质量管理的基石。例如&#xff0c;某全球500强企业通过引入ISO 9001体系&#xff0c;将项目缺陷率降低了37%。标准化流程不仅能明确各环节的质量要求&#xff0c;还…

                      2025web寒假作业二

                      一、整体功能概述 该代码构建了一个简单的后台管理系统界面&#xff0c;主要包含左侧导航栏和右侧内容区域。左侧导航栏有 logo、管理员头像、导航菜单和安全退出按钮&#xff1b;右侧内容区域包括页头、用户信息管理内容&#xff08;含搜索框和用户数据表格&#xff09;以及页…

                      服务器ip被反垃圾列为黑名单

                      查询 BarracudaCentral.org - Technical Insight for Security Pros https://multirbl.valli.org/lookup/ 大概写&#xff1a;我不知道这个IP在我使用之前已被列入Barracuda信誉阻止列表&#xff08;BRBL&#xff09;。我不知道它之前列出的原因&#xff0c;但服务器现在有了…