更新时间:2025-09-19 GMT+08:00
分享

全密态数据库

全密态数据库是指能够解决数据全生命周期的隐私保护问题,使得系统无论在何种业务场景和环境下,数据在传输、运算以及存储的各个环节始终都处于密文状态,同时密钥掌握在授权用户手中的数据库管理系统。

加密模型

全密态数据库使用多级加密模型,加密模型中涉及3个对象:数据、列密钥和主密钥,以下是对3个对象的介绍。

  • 数据:
    1. SQL语法中包含的数据,比如INSERT... VALUES ('data')语法中包含'data'。
    2. 从数据库服务端返回的查询结果,如执行SELECT语法返回的查询结果。

    密态数据库会在驱动中,对SQL语法中属于加密列的数据进行加密,对数据库服务端返回的属于加密列的查询结果进行解密。

  • 列密钥:数据由列密钥进行加密,列密钥由数据库驱动生成或由用户手动导入,列密钥密文存储在数据库服务端。
  • 主密钥:列密钥由主密钥加密,主密钥由外部密钥管理者生成并存储。数据库驱动会自动访问外部密钥管理者,以实现对列密钥进行加解密。目前支持Huawei KMS、 user_token进行密钥管理。
    图1 全密态数据库加密模型

密钥管理

全密态数据库目前支持Huawei KMS、user_token进行密钥管理。

  • Huawei KMS:由华为云提供的在线密钥管理服务,提供创建、删除、查询和备份密钥等功能,并支持在线使用密钥对数据进行加解密。
  • user_token:由用户提供的密码在客户端派生密钥,或者直接对接密钥。

数据库驱动

全密态数据库目前支持的数据库驱动有gsql、JDBC和GO驱动。

内存加解密模式

内存加解密模式是在密态等值查询的基础上,将密钥传输到数据库内存中,对数据进行解密,以实现密文字段的特殊计算或查询功能,包括范围查询、排序。其他涉及密文操作、隐式或显式类型转换时,进行自动加解密。

示例-使用gsql操作密态数据库

执行SQL语句前,请确保已提前生成主密钥,并确认访问主密钥的参数。

本示例以完整的执行流程为例,介绍如何使用密态数据库语法,包括三个阶段:使用DDL阶段、使用DML阶段、清理阶段。

  1. 连接数据库,并通过-C参数开启全密态开关

    gsql -p PORT -d DATABASE -h HOST -U USER -W PASSWORD -r -C

  2. 通过元命令设置访问主密钥的参数

    注意:从keyType字符串开始,不要添加换行,不要添加空格,否则gsql工具无法识别完整参数

    华为云支持两种认证方式,两种认证方式的参数个数与参数类型不同,选择其中一种方式即可。

    • 认证方式一 aksk认证
      gaussdb=# \key_info keyType=huawei_kms,kmsProjectId={项目ID},ak={AK},sk={SK}

      参数获取:生成主密钥阶段介绍了如何获取相关参数:项目ID、AK、SK。

      示例:\key_info keyType=huawei_kms,kmsProjectId=0b59929e8100268a2f22c01429802728,ak=XMAUMJY******DFWLQW,sk=ga6rO8lx1Q4uB*********2gf80muIzUX

    • 认证方式二 账号密码认证
      gaussdb=# \key_info keyType=huawei_kms,iamUrl={IAM服务器地址},iamUser={IAM用户名},iamPassword={IAM用户密码},iamDomain={账号名},kmsProject={项目}

      参数获取:生成主密钥阶段介绍了如何获取相关参数:IAM服务器地址、IAM用户名、IAM用户密码、账号名、项目。

      示例:\key_info keyType=huawei_kms,iamUrl=https://iam.example.com/v3/auth/tokens,iamUser=test,iamPassword=*********,iamDomain=test_account,kmsProject=xxx

  3. 定义主密钥

    在生成主密钥阶段,密钥服务已生成并存储主密钥,执行本语法只是将主密钥的相关信息存储在数据库中,方便以后访问。该语法详细格式参考CREATE CLIENT MASTER KEY章节。
    gaussdb=# CREATE CLIENT MASTER KEY cmk1 WITH ( KEY_STORE = huawei_kms , KEY_PATH = '{KMS服务器地址}/{密钥ID}', ALGORITHM = AES_256);
    CREATE CLIENT MASTER KEY
    • 参数获取:生成主密钥阶段介绍了如何获取如下参数:KMS服务器地址、密钥ID。

      KEY_PATH示例:https://kms.cn-north-4.myhuaweicloud.com/v1.0/0b59929e8100268a2f22c01429802728/kms/9a262917-8b31-41af-a1e0-a53235f32de9

  4. 定义列密钥

    列密钥由上一步定义的主密钥加密。详细语法参考CREATE COLUMN ENCRYPTION KEY章节。
    gaussdb=# CREATE COLUMN ENCRYPTION KEY cek1 WITH VALUES (CLIENT_MASTER_KEY = cmk1, ALGORITHM = AES_256_GCM);

  5. 定义加密表

    本示例中,通过语法指定表中name和credit_card为加密列。
    gaussdb=# CREATE TABLE creditcard_info (
      id_number int,
      name text encrypted with (column_encryption_key = cek1, encryption_type = DETERMINISTIC),
      credit_card varchar(19) encrypted with (column_encryption_key = cek1, encryption_type = DETERMINISTIC));
    CREATE TABLE

  6. 对加密表进行其他操作

    -- 向加密表写入数据。
    gaussdb=# INSERT INTO creditcard_info VALUES (1,'joe','6217986500001288393');
    INSERT 0 1
    gaussdb=# INSERT INTO creditcard_info VALUES (2, 'joy','6219985678349800033');
    INSERT 0 1
    
    -- 从加密表中查询数据。
    gaussdb=# select * from creditcard_info where name = 'joe';
     id_number | name |     credit_card
    -----------+------+---------------------
             1 | joe  | 6217986500001288393
    
    -- 更新加密表中数据。
    gaussdb=# update creditcard_info set credit_card = '80000000011111111' where name = 'joy';
    UPDATE 1
    
    -- 向表中新增一列加密列。
    gaussdb=# ALTER TABLE creditcard_info ADD COLUMN age int ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = cek1, ENCRYPTION_TYPE = DETERMINISTIC);
    ALTER TABLE
    
    -- 从表中删除一列加密列。
    gaussdb=# ALTER TABLE creditcard_info DROP COLUMN age;
    ALTER TABLE
    
    -- 从系统表中查询主密钥信息。
    gaussdb=# SELECT * FROM gs_client_global_keys;
     global_key_name | key_namespace | key_owner | key_acl |        create_date
    -----------------+---------------+-----------+---------+----------------------------
     cmk1            |          2200 |        10 |         | 2021-04-21 11:04:00.656617
    (1 rows)
    
    -- 从系统表中查询列密钥信息。
    gaussdb=# 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
    -----------------+---------------------------+---------------+-----------
     cek1            |                 760411027 |         16392 |        10
    (1 rows)
    
    -- 查看表中列的元信息。
    gaussdb=# \d creditcard_info
            Table "public.creditcard_info"
       Column    |       Type        | Modifiers
    -------------+-------------------+------------
     id_number   | integer           |
     name        | text              |  encrypted
     credit_card | character varying |  encrypted

  7. 清理阶段

    -- 删除加密表。
    gaussdb=# DROP TABLE creditcard_info;
    DROP TABLE
    
    -- 删除列密钥。
    gaussdb=# DROP COLUMN ENCRYPTION KEY cek1;
    DROP COLUMN ENCRYPTION KEY
    
    -- 删除主密钥。
    gaussdb=# DROP CLIENT MASTER KEY cmk1;
    DROP CLIENT MASTER KEY

相关文档