基于openGauss5.0.0全密态数据库等值查询小案例

基于openGauss5.0.0全密态数据库等值查询小案例

一、全密态数据库简介

  1. 价值体现:
    密态数据库意在解决数据全生命周期的隐私保护问题,使得系统无论在何种业务场景和环境下,数据在传输、运算以及存储的各个环节始终都处于密文状态。当数据拥有者在客户端完成数据加密并发送给服务端后,在攻击者借助系统脆弱点窃取用户数据的状态下仍然无法获得有效的价值信息,从而起到保护数据隐私的作用。

2. 特性介绍

从用户视角来看,整个密态等值查询的主要功能分为三部分,主要通过新增的KeyTool工具以及openGauss的增强gsql客户端来实现。
首先是客户端密钥管理功能,用户借助新增的KeyTool工具来实现CMK的生成、销毁和更新,同时支持密钥导入导出。通过该KeyTool工具的导入导出功能,CMK可以在不同的客户端间进行传输;同时,KeyTool实现了单个客户端侧的密钥管理,通过配置管理文件,可以对密钥的存储、更新进行管理。
其次该特性提供密钥创建功能和加密表创建功能,通过新增SQL语法"CREATE CLINET MASTER KEY"和"CREATE COLUMN ENCRYPTION KEY"实现在数据库侧记录和管理CMK和CEK元信息,CMK和CEK信息被记录在新增的系统表中。通过扩展"CREATE TABLE"语法为表的每一个敏感信息列指定列加密密钥和加密算法,方便后续数据密文存储。
最后该特性对用户提供密态等值查询能力,该部分功能是整个特性的核心,虽然用户对整个密文查询无感知,但是在指定数据的加密信息后,针对该敏感数据的查询将受限于当前密态等值查询的支持规格。

从整体视角来看,该特性所实现的功能主要是为了用户基于敏感数据保护的诉求来存储管理数据并基于密文数据信息实现查询任务。

二、环境说明

  1. 虚拟机:virtualbox
  2. 操作系统:openEuler 20.03 TLS SP1
  3. 数据库:openGauss 5.0.0 单节点部署

三、测试步骤

  1. 创建密钥 2. 创建加密表 3. 全密态等值查询

  2. 创建密钥

    • 创建密钥前,需要规划好本地密钥存储路径,且须保证数据库用户(如omm)具有操作该路径的权限。本案例路径为:/opt/software/openGauss,且该路径目录及文件所属组为omm:dbgrp

    • 将该路径下配置到数据库用户下的环境变量配置文件中,如omm用户下的~/.bashrc

      shell 复制代码
      echo "export LOCALKMS_FILE_PATH=/opt/software/openGauss" >> ~/.bashrc
    • 环境变量生效

      shell 复制代码
      source ~/.bashrc
    • 以gsql全密态方式登录数据库,-C表示开启密态开关

      shell 复制代码
      gsql -d postgres -p 15432 -r -C
    • 创建密钥
      密钥包括CMKCEKCMK是主密钥用于加密CEK;而CEK是数据密钥,用于加密数据。CEK的创建要依赖于CMK,因此要先创建CMK再创建CEK重要说明 :当前KEY_STORE仅支持localkms,ALGORITHM 支持RSA_2048、RSA3072和SM2;由于SM2、SM3、SM4等算法属于中国国家密码标准算法,为规避法律风险,需配套使用。如果创建CMK时指定SM4算法来加密CEK,则创建CEK时必须指定SM4_SM3算法来加密数据。

      sql 复制代码
      CREATE CLIENT MASTER KEY ImgCMK WITH (KEY_STORE = localkms, KEY_PATH = "key_path_value", ALGORITHM = RSA_2048);
      CREATE COLUMN ENCRYPTION KEY ImgCEK WITH VALUES (CLIENT_MASTER_KEY = ImgCMK, ALGORITHM = AEAD_AES_256_CBC_HMAC_SHA256);


      命令执行成功后,会在本地生成密钥文件,如下所示:

    • 查看系统表,检查是否有密钥信息:

      sql 复制代码
      openGauss=# SELECT * FROM gs_client_global_keys;
       global_key_name | key_namespace | key_owner | key_acl |        create_date
      -----------------+---------------+-----------+---------+----------------------------
       imgcmk          |          2200 |        10 |         | 2023-12-26 09:32:26.048963
      (1 row)
      
      openGauss=# SELECT column_key_name,column_key_distributed_id ,global_key_id,key_owner FROM gs_column_keys;
       column_key_name | column_key_distributed_id | global_key_id | key_owner
      -----------------+---------------------------+---------------+-----------
       imgcek          |                3618369306 |         33446 |        10
      (1 row)
  3. 创建加密表

    • 创建加密表

      sql 复制代码
      CREATE TABLE creditcard_info (id_number int, name text encrypted with (column_encryption_key = ImgCEK, encryption_type = DETERMINISTIC),credit_card  varchar(19) encrypted with (column_encryption_key = ImgCEK, encryption_type = DETERMINISTIC));
    • 查看表结构

      shell 复制代码
      openGauss=# \d+ creditcard_info;
                          Table "public.creditcard_info"
         Column    |       Type        | Modifiers  | Storage  | Stats target | Description
      -------------+-------------------+------------+----------+--------------+-------------
       id_number   | integer           |            | plain    |              |
       name        | text              |  encrypted | extended |              |
       credit_card | character varying |  encrypted | extended |              |
      Has OIDs: no
      Options: orientation=row, compression=no
    • 插入表数据

      sql 复制代码
      INSERT INTO creditcard_info VALUES(1,'joe','6217986500001288393'),(2, 'joy','6219985678349800033');
  4. 全密态等值查询

    • 第一种查询方式:开启密态开关进行查看
      gsql登录数据库,查看如下:全以正常明文显示结果且支撑在加密列上进行等值查询。

      shell 复制代码
      [omm@openEuler02 openGauss]$ gsql -d postgres -p 15432 -r -C
      openGauss=# select * from public.creditcard_info;
       id_number | name |     credit_card
      -----------+------+---------------------
               1 | joe  | 6217986500001288393
               2 | joy  | 6219985678349800033
      (2 rows)
      
      openGauss=# select * from public.creditcard_info where name = 'joe';
       id_number | name |     credit_card     
      -----------+------+---------------------
               1 | joe  | 6217986500001288393
      (1 row)
      
      openGauss=# select * from public.creditcard_info where name = 'joy';
       id_number | name |     credit_card     
      -----------+------+---------------------
               2 | joy  | 6219985678349800033
      (1 row)
    • 第二种查询方式:关闭密态开关进行查看,结果如下:加密列全部以密文方式呈现。且无法使用加密列作为等值查询的列或条件。

      sql 复制代码
      [omm@openEuler02 openGauss]$ gsql -p 15432 -d postgres -r 
      gsql ((openGauss 5.0.0 build a07d57c3) compiled at 2023-03-29 03:09:38 commit 0 last mr  )
      Non-SSL connection (SSL connection is recommended when requiring high-security)
      Type "help" for help.
      
      openGauss=# \d
                                    List of relations
       Schema |      Name       | Type  | Owner |             Storage
      --------+-----------------+-------+-------+----------------------------------
       public | creditcard_info | table | omm   | {orientation=row,compression=no}
      (1 row)
      
      openGauss=# select * from creditcard_info;
       id_number |                                                                         name                                                                         |
                                               credit_card
      -----------+------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
               1 | \x011aefabd7469d77248aa31885878bb77607981efec65eff3271053e44b45d639d8976168a31000000dd1092fa8926f98b29d736c9553472bb821d07b9a6ba5ee5d0439e5e73a8adc9 | \x011aefabd79ce3f9ef953994577ecf46395b118f38d3b70a0e55b2c29d4a7817a15ac70799310000004b7153b0fd01156b87abf1ca3f53632a5810777da8cc1a3143dad27e1962bf6bda021e7bd718b40ddc0b3a9ec1ef260d
               2 | \x011aefabd72d06b1228a54a522593d47e067ee949b2e0e69e53c25832141bc1e9b44b922533100000095340c76388706c6551fb67972049c2c09c1b50360e0f3b4e19ab29c84d759f3 | \x011aefabd7b54376da6c719bae031a02cb248bccacfc37008f328ad889b6a7e08aa4a766613100000002379e139f7a9cf407f8e4a1b16ae959120491a787c02eba3c9f4394b799c70ac0a4f5debeeb5a7e312c94e4c71bd1cf
      (2 rows)
      
      openGauss=# select * from creditcard_info where name = 'joy';
      ERROR:  invalid input syntax for type byteawithoutorderwithequalcol
      LINE 1: select * from creditcard_info where name = 'joy';
                                                         ^
      openGauss=# select * from public.creditcard_info where name = 'joe';
      ERROR:  invalid input syntax for type byteawithoutorderwithequalcol
      LINE 1: select * from public.creditcard_info where name = 'joe';
                                                                ^
      openGauss=#
    • 第三种查询方式:新建新用户且授予查看表等权限进行查看
      新建普通用户,如testuser

      sql 复制代码
      [omm@openEuler02 openGauss]$ gsql -d postgres -p 15432 -r -C
      gsql ((openGauss 5.0.0 build a07d57c3) compiled at 2023-03-29 03:09:38 commit 0 last mr  )
      Non-SSL connection (SSL connection is recommended when requiring high-security)
      Type "help" for help.
      
      openGauss=# create user testuser password 'openGauss@1234';
      CREATE ROLE
      openGauss=# grant all privileges on public.creditcard_info to testuser;
      GRANT

      使用新用户testuser登录到数据库中,执行查询语句,具体如下:

      sql 复制代码
      [omm@openEuler02 openGauss]$ gsql -d postgres -p 15432 -U testuser -W openGauss@1234 -r -C
      gsql ((openGauss 5.0.0 build a07d57c3) compiled at 2023-03-29 03:09:38 commit 0 last mr  )
      Non-SSL connection (SSL connection is recommended when requiring high-security)
      Type "help" for help.
      
      openGauss=> \d
                                    List of relations
       Schema |      Name       | Type  | Owner |             Storage
      --------+-----------------+-------+-------+----------------------------------
       public | creditcard_info | table |       | {orientation=row,compression=no}
      (1 row)
      
      openGauss=> select * from creditcard_info;
      ERROR(CLIENT): failed to decrypt column encryption key
      openGauss=> select * from creditcard_info where name = 'joe';
      ERROR:  invalid input syntax for type byteawithoutorderwithequalcol
      LINE 1: select * from creditcard_info where name = 'joe';
                                                         ^
      openGauss=> \d+ creditcard_info
                                  Table "public.creditcard_info"
         Column    |       Type        | Modifiers  | Storage  | Stats target | Description
      -------------+-------------------+------------+----------+--------------+-------------
       id_number   | integer           |            | plain    |              |
       name        | text              |  encrypted | extended |              |
       credit_card | character varying |  encrypted | extended |              |
      Has OIDs: no
      Options: orientation=row, compression=no
      
      openGauss=> select id_number from creditcard_info;
       id_number
      -----------
               1
               2
      (2 rows)
      
      openGauss=>

      由此,可看出:

      • 无论是否打开密态开关,都无法查询到加密数据,报错如下:ERROR(CLIENT): failed to decrypt column encryption key
      • 非加密列查询是正常的,如id_number列是正常显示

四、使用约束

数据以列级别进行加密,而无法按照行级别区分加密策略。

除Rename操作外,不支持通过Alter Table语法实现对加密表列的更改(包括加密列和非加密列之间的互转换),支持添加(Add)和删除(Drop)对应的加密列。不支持对加密列设置大部分check限制性语法,但是支持check(column is not null)语法。

当support_extended_features = off时,不支持对加密列使用primary key、unique。当support_extended_features = on时,仅支持确定性加密列使用primary key、unique。

不支持不同数据类型之间的隐式转换。

不支持不同数据类型密文间的集合操作。

不支持加密列创建范围分区。

加密列仅支持repeat和empty_blob()函数。

当前版本只支持gsql和JDBC(部署在linux操作系统)客户端,暂不支持ODBC等其他客户端实现密态等值查询。

使用JDBC客户端时,密态等值查询特性不能与负载均衡或自动选主特性同时开启。

只支持通过客户端执行copy from stdin的方式、\copy命令的方式以及insert into values(...)的方式往密态表中导入数据。

不支持从加密表到文件之间的copy操作。

不支持包括排序、范围查询以及模糊查询等在内的除等值以外的各种密态查询。

支持部分函数存储过程密态语法,密态支持函数存储过程具体约束查看《数据库管理》数据安全管理/密态支持函数/存储过程章节。

不支持通过insert into...select...、merge into语法将非加密表数据插入到加密表数据中。

对于处于连接状态的连接请求,只有触发更新缓存的操作(更改用户、解密加密列失败等)和重新建连后才能感知服务端CEK信息变更。

不支持在由随机加密算法加密的列上进行密态等值查询。

对于密态等值查询运算中如果参与比较的两个属性条件采用不同的数据加密密钥,返回报错。

密态等值查询不支持时序表、外表,不支持ustore存储引擎加密。

对于数据库服务侧配置变更(pg_settings系统表、权限、密钥和加密列等信息), 需要重新建立JDBC连接保证配置变更生效。

不支持多条SQL语句一起执行,insert into语句多批次执行场景不受此条约束限制。

密态数据库对长度为零的空字符串不进行加密。

确定性加密存在频率攻击的潜在风险,不建议在明文频率分布明显的场景下使用。

具体可参考官网:全密态等值查询

到此,简单的openGauss 5.0.0全密态等值查询到此结束,感谢大家查阅,希望对你们有所帮助!!!

相关推荐
赵渝强老师7 天前
【赵渝强老师】高斯数据库(openGauss)的模式
数据库·opengauss·国产数据库·高斯数据库
赵渝强老师25 天前
【赵渝强老师】openGauss的数据库
数据库·opengauss·国产数据库·高斯数据库
赵渝强老师4 个月前
【赵渝强老师】高斯数据库(openGauss)的逻辑存储结构
数据库·postgresql·opengauss·gaussdb·国产数据库·高斯数据库
赵渝强老师4 个月前
【赵渝强老师】高斯数据库(openGauss)的体系架构
数据库·postgresql·opengauss·gaussdb·国产数据库
Gauss松鼠会4 个月前
【GaussDB】GaussDB 表的创建与使用之临时表
数据库·database·opengauss·gaussdb
Gauss松鼠会4 个月前
openGauss数据库源码解析系列文章——存储引擎源码解析(一)
数据库·oracle·性能优化·database·opengauss
Gauss松鼠会4 个月前
openGauss数据库源码解析系列文章--openGauss简介(上)
数据库·性能优化·database·opengauss
一点多余.5 个月前
openGauss 企业版安装全流程指南
linux·数据库·opengauss·企业版
king_harry5 个月前
openGauss 6.0 主备集群备份与恢复实战指南:基于 gs_probackup
数据库·opengauss·gs_probackup
IvanCodes5 个月前
openGauss 实战手册:gsql 常用命令、认证配置与运维工具全解
大数据·数据库·sql·opengauss