【GaussDB】全密态等值查询功能测试

一、引言

全密态要解决的问题重点在于,认为服务提供方是不可信的,即网络传输和数据库存储都可能存在数据泄露的风险,因此网络传输和数据库存储都要加密,且要求服务提供方无法自行解密,只有受信的客户端能解密。

由于常规的数据库设计,SQL执行层都是在数据库服务端,必然会涉及到对数据的访问和计算,因此最大的难点就在于如何在数据库自身无法解密数据的情况下还能对数据进行访问和计算。在这种限制下,就连最简单的等值查询都有技术挑战,除非使用确定性加密,但确定性加密,对于重复度高的数据,很容易破解,比如性别。

全密态的最终目标是全同态,即能支持任意类型的计算(比如 ,在不知道密钥的情况下,能计算出”1的密文加2的密文等于3的密文“)。虽然全同态至今已经发展了几十年,但现有的全同态方案效率仍然是极低,如果把全同态技术放在通用的数据库软件里,其性能的削减程度是无法接受的。

二、基本测试

创建用户

gaussdb=# CREATE USER alice PASSWORD 'Gaussdb@123';
CREATE ROLE
gaussdb=# \q

gsql全密态连接

连接时要加 -C ,如果是其他客户端,需要使用对应的全密态版本驱动或加载对应的动态库

[gaussdb@01c3b6b51da2 data]$ gsql -d postgres -U alice -WGaussdb@123 -r -C
gsql ((GaussDB Kernel 506.0.0.SPC0100 build e324981f) compiled at 2025-04-27 14:27:52 last mr 23420 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

设置密钥

注意每次使用密态连接都要先设置密钥。当密钥类型为user_token时,表示不依赖外部服务或硬件,此时只需要设置密码;另外可选的有华为云在线的kms或者第三方加密卡的kms

gaussdb=> \key_info keyType=user_token,password=Gaussdb@123

注:openGauss的本地密钥和GaussDB的user_token不一样,openGauss的叫
localkms,以文件形式保存在服务端,无需密码;而GaussDB的user_token仅在客户端,服务端不进行存储也无法主动获知。

创建主密钥

在key_store里选择刚刚设置的类型

gaussdb=> CREATE CLIENT MASTER KEY alice_cmk WITH ( KEY_STORE = user_token , ALGORITHM = AES_256_GCM );
CREATE CLIENT MASTER KEY

创建列密钥

gaussdb=> CREATE COLUMN ENCRYPTION KEY cek1 WITH VALUES (CLIENT_MASTER_KEY = alice_cmk, ALGORITHM = AES_256_GCM);
CREATE COLUMN ENCRYPTION KEY

创建具有加密列的表,并插入数据

gaussdb=> CREATE TABLE creditcard_info (
gaussdb(>   id_number int,
gaussdb(>   name text encrypted with (column_encryption_key = cek1, encryption_type = DETERMINISTIC),
gaussdb(>   credit_card varchar(19) encrypted with (column_encryption_key = cek1, encryption_type = DETERMINISTIC));
CREATE TABLE
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
(1 row)

更新数据

也能正常更新

gaussdb=> update creditcard_info set credit_card = '80000000011111111' where name = 'joy';
UPDATE 1

模糊查询

加密列无法模糊查询

gaussdb=> select * from creditcard_info where name like 'j%';
ERROR(CLIENT): operator is not allowed on datatype of this column

范围查询

加密列无法范围查询

gaussdb=> select * from creditcard_info where name >'a';
ERROR(CLIENT): operator is not allowed on datatype of this column
gaussdb=> \q

使用非密态连接

[gaussdb@01c3b6b51da2 data]$ gsql -d postgres -U alice -WGaussdb@123 -r 
gsql ((GaussDB Kernel 506.0.0.SPC0100 build e324981f) compiled at 2025-04-27 14:27:52 last mr 23420 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

对加密列进行等值查询

报错

gaussdb=> select * from creditcard_info where name = 'joe';
ERROR:  The entered syntax is not supported by the byteawithoutorderwithequalcol type.
LINE 1: select * from creditcard_info where name = 'joe';
                                                   ^

不带过滤条件进行查询

能看到加密列的数据都为密文,而且长度已经超过了定义的长度

 gaussdb=> select * from creditcard_info;  id_number |                 

> name                                        |                         
> credit_car d                                     
> -----------+------------------------------------------------------------------------------------+--------------------------------------------------------------
> ------------------------------------------------------
>          1 | 

\x01eaa587da4b8a0ed0d3ec32ce1284a6e1b82e69d4310000000d5762f944388244665aa54c12b31b

| \x01eaa587dab33533b2e2114abbd025a680f72cf95231000000cedfd5255
e15ade775ec81d734c2dc4ea4277aad3d70bad0eb38e3121bac45
2 | \x01eaa587da331c34df8a04c86ae4d1ed3102d0738631000000102d852e9ce5d5c388c21ab793463e
| \x01eaa587da8e633482090e8b78f79598d11ec27486310000007cd9ea54c
fc38269b6a2a14f1bb5e814774b45bbd317188b6b7eb176ce (2 rows)

表结构显示

虽然字段类型显示为varchar,但实际上已经已经变成了二进制类型

gaussdb=> \dS+ creditcard_info
                            Table "alice.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, storage_type=USTORE, segment=off, toast.storage_type=USTORE, toast.toast_storage_type=enhanced_toast

gaussdb=>

三、内存解密逃生通道

内存解密作为密态等值查询的一个逃生通道使用。在该逃生通道中,会将密钥传输到数据库内存中,对数据进行解密,以实现密文字段的特殊计算或查询功能,包括范围查询、排序;其他涉及密文操作、隐式或显式类型转换时,进行自动加解密。

逃生连接

加-C3进行连接

[gaussdb@01c3b6b51da2 data]$ gsql -d postgres -U alice -WGaussdb@123 -r -C3
gsql ((GaussDB Kernel 506.0.0.SPC0100 build e324981f) compiled at 2025-04-27 14:27:52 last mr 23420 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

设置密钥信息

gaussdb=> \key_info keyType=user_token,password=Gaussdb@123

默认情况,非等值查询报错

gaussdb=> select * from creditcard_info where name like 'j%';
ERROR:  The entered syntax is not supported by the byteawithoutorderwithequalcol type.
LINE 1: select * from creditcard_info where name like 'j%';
                                                      ^

传输密钥后再使用非等值查询,不报错

gaussdb=> \st
Token cache enabled in Trusted Domain.
gaussdb=> select * from creditcard_info where name like 'j%';
 id_number | name |     credit_card   
-----------+------+---------------------
         1 | joe  | 6217986500001288393
         2 | joy  | 80000000011111111
(2 rows)

四、FAQ

透明加密和全密态有什么区别?
答:透明加密和全密态都可以加密数据,但这是两种不同的加密模式,具体区别如下:

加密位置不同:透明加密在数据库存储模块后加密,全密态在数据库驱动中加密。
加密对象不同:透明加密数据页中的全部数据,全密态加密SQL语句中的某几列数据。
加密性能不同:透明加密一次可以处理8k的数据页,全密态一次仅可以处理SQL语句中的一条数据,透明加密性能高于全密态。
安全性不同:全密态安全性高于透明加密。

五、总结

GaussDB的全密态等值查询功能测试基本符合预期,但是用户必须要清楚其使用场景。使用全密态的副作用并不仅仅是性能下降那么简单,其原理上就限制了非常多的使用场景是无法支持的。
不过如果期望的效果是数据库服务器最高权限被黑,网络被黑,涉密数据也不会明文泄露,那么全密态可能是唯一的选择了。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐