511 lines
16 KiB
Markdown
Executable File
511 lines
16 KiB
Markdown
Executable File
# Enc-db配置方法
|
||
|
||
## 1. 安装环境
|
||
|
||
> Ubuntu 20.04
|
||
> gcc version 9.4.0
|
||
|
||
### 1.1 依赖项
|
||
|
||
```shell
|
||
sudo apt-get update
|
||
sudo apt-get install -y build-essential libreadline-dev zlib1g-dev libssl-dev libxml2-dev libxslt-dev cmake
|
||
sudo apt-get install -y make automake libtool git
|
||
sudo apt-get install -y libssl-dev libboost-all-dev lzip
|
||
sudo apt-get install -y protobuf-compiler libprotobuf-dev
|
||
sudo apt-get install -y libjsoncpp-dev
|
||
|
||
# 安装gmp依赖
|
||
wget https://gmplib.org/download/gmp/gmp-6.2.1.tar.lz
|
||
tar -xf gmp-6.2.1.tar.lz
|
||
cd gmp-6.2.1
|
||
CFLAGS="-fPIC" ./configure
|
||
make -j4
|
||
sudo make install
|
||
|
||
# 安装log4cpp日志
|
||
wget http://sourceforge.net/projects/log4cpp/files/log4cpp-1.1.3.tar.gz
|
||
tar -xvzf log4cpp-1.1.3.tar.gz
|
||
cd log4cpp
|
||
./configure
|
||
make
|
||
sudo make install
|
||
|
||
# 安装国密依赖
|
||
git clone https://github.com/guanzhi/GmSSL.git
|
||
cd GmSSL
|
||
mkdir build
|
||
cd build
|
||
cmake ..
|
||
make
|
||
make test
|
||
sudo make install
|
||
```
|
||
|
||
### 1.2 PostgreSQL安装
|
||
|
||
现版本为PostgreSQL-14.2
|
||
|
||
```shell
|
||
# 下载安装PostgreSQL-14.2
|
||
wget https://ftp.postgresql.org/pub/source/v14.2/postgresql-14.2.tar.gz
|
||
tar -xzvf postgresql-14.2.tar.gz
|
||
|
||
# 解压本项目EncDB,并放到postgresql-14.2/src/interfaces/libpq路径下
|
||
unzip encryptsql.zip
|
||
cp -r encryptsql/ postgresql-14.2/src/interfaces/libpq/
|
||
|
||
# 将pg编译到/usr/local/postgresql路径下
|
||
sudo mkdir /usr/local/postgresql
|
||
cd postgresql-14.2
|
||
./configure --enable-debug --enable-cassert --prefix=/usr/local/postgresql CFLAGS=-O0
|
||
sudo make -j `nproc`
|
||
|
||
# 编译encdb
|
||
cd src/interfaces/libpq/encryptsql/
|
||
|
||
rm -f ../Makefile
|
||
cp replaced_file/Makefile.libpq.14 ../Makefile
|
||
rm -f ../../../bin/psql/Makefile
|
||
cp replaced_file/Makefile.psql.14 ../../../bin/psql/Makefile
|
||
cp replaced_file/fe-exec.14.c ../
|
||
rm ../fe-exec.c
|
||
mv ../fe-exec.14.c ../fe-exec.c
|
||
sudo mkdir -p /etc/encryptsql/enclave
|
||
sudo cp config.json /etc/encryptsql/
|
||
ln -s ../../../include db_include
|
||
|
||
rm -rf build
|
||
mkdir build && cd build
|
||
cmake .. \
|
||
-DENCRYPTSQL_INSTALL_DIR=/usr/local/postgresql \
|
||
-DENCRYPTSQL_CONFIG_DIR=/etc/encryptsql \
|
||
-DDK_SERVER_HOST=127.0.0.1 \
|
||
-DDK_SERVER_PORT=9443
|
||
sudo make -j `nproc`
|
||
|
||
cd ../../../../../
|
||
cmake --build src/interfaces/libpq/encryptsql/build --target enclave.signed.so -j"$(nproc)"
|
||
cp /etc/encryptsql/enclave.signed.so src/interfaces/libpq/encryptsql/build/lib/enclave.signed.so
|
||
make install
|
||
|
||
sudo rm /usr/local/postgresql/lib/libudf.so
|
||
sudo cp src/interfaces/libpq/encryptsql/build/lib/libudf.so /usr/local/postgresql/lib
|
||
|
||
sudo rm /usr/local/postgresql/lib/libencryptsql.so
|
||
sudo cp src/interfaces/libpq/encryptsql/build/lib/libencryptsql.so /usr/local/postgresql/lib
|
||
|
||
sudo cp src/interfaces/libpq/encryptsql/createudf.sql /usr/local/postgresql/
|
||
sudo cp src/interfaces/libpq/encryptsql/map.json /etc/encryptsql
|
||
sudo cp src/interfaces/libpq/encryptsql/mask_funcs.sql /usr/local/postgresql/
|
||
|
||
sudo cp src/interfaces/libpq/encryptsql/build/bin/backup /usr/local/postgresql/bin/
|
||
sudo cp src/interfaces/libpq/encryptsql/build/bin/restore /usr/local/postgresql/bin/
|
||
|
||
# 创建cmk存储路径
|
||
sudo mkdir -p /etc/encryptsql/kms_test
|
||
sudo cp src/interfaces/libpq/encryptsql/src/KMS/domainkey /etc/encryptsql/kms_test/
|
||
|
||
cd /etc/encryptsql
|
||
sudo chmod 777 map.json
|
||
|
||
# 创建kms_root根密钥相关文件
|
||
sudo mkdir -p /etc/encryptsql/kms_root
|
||
|
||
cd /etc/encryptsql/kms_root
|
||
sudo head -c 16 /dev/urandom > frag_a
|
||
sudo head -c 16 /dev/urandom > frag_b
|
||
sudo head -c 16 /dev/urandom > frag_c
|
||
```
|
||
|
||
### 1.3 配置数据库
|
||
|
||
```shell
|
||
cd /usr/local/postgresql
|
||
sudo mkdir data
|
||
sudo useradd -m -s /bin/bash postgres
|
||
sudo passwd postgres
|
||
sudo chown postgres:postgres data
|
||
su postgres
|
||
|
||
vim ~/.bashrc
|
||
#vim打开后 将下面export开头内容插入到内部并保存
|
||
export PGHOME=/usr/local/postgresql
|
||
export PGDATA=$PGHOME/data
|
||
export PGPORT=5432
|
||
export PGUSER=postgres
|
||
export PATH=$PGHOME/bin:$PATH:$HOME/bin
|
||
export LD_LIBRARY_PATH=$PGHOME/lib
|
||
source ~/.bashrc
|
||
|
||
initdb
|
||
|
||
vim /usr/local/postgresql/data/postgresql.conf
|
||
# vim 打开后,将下面内容加入到尾部
|
||
shared_preload_libraries = 'keydist_receiver'
|
||
keydist.listen_host = '127.0.0.1'
|
||
keydist.listen_port = '9443'
|
||
keydist.enclave_signed_path = '/new_enc/postgresql-14.2/src/interfaces/libpq/encryptsql/build/bin/tls_server_enclave.signed'
|
||
|
||
|
||
pg_ctl start
|
||
|
||
su root
|
||
cd bin
|
||
./psql -U postgres
|
||
```
|
||
## 2. 使用说明
|
||
|
||
### 2.1 功能准备
|
||
|
||
```sql
|
||
create user dekmaster with password 'secure_password';
|
||
|
||
create database dekmaster owner dekmaster;
|
||
|
||
GRANT ALL PRIVILEGES ON DATABASE dekmaster TO dekmaster;
|
||
|
||
\q
|
||
```
|
||
|
||
```shell
|
||
./psql -U dekmaster -d dekmaster
|
||
```
|
||
|
||
配置DEK表
|
||
|
||
```sql
|
||
create table dek_store(
|
||
username text,
|
||
db text,
|
||
t text,
|
||
c text,
|
||
dek text);
|
||
\q
|
||
```
|
||
### 2.2 测试使用
|
||
|
||
```shell
|
||
./psql -U postgres -d postgres
|
||
```
|
||
|
||
进入psql客户端
|
||
|
||
#### 1. 密钥创建、建表插入查询功能
|
||
|
||
```sql
|
||
--导入密态UDF函数
|
||
\i ../createudf.sql
|
||
|
||
--启动加密环境
|
||
--(enc status可查询数据库enc加密状态,1为on开启中,0为off已关闭)
|
||
enc on;
|
||
|
||
--创建CMK,并设置轮转周期(天)
|
||
create cmk -rotate_period=30;
|
||
|
||
--创建表
|
||
CREATE TABLE sample_table (
|
||
id int PRIMARY KEY,--数值明文
|
||
datetime date,--日期明文
|
||
name varchar(255) encrypted(eq),--字符密文,确定性加密
|
||
brand char(20) encrypted(rnd) NOT NULL,--字符密文,非确定性加密
|
||
amount int4 encrypted(eq, cal),--int4数值密文,确定性加密+同态加密
|
||
price int8 encrypted(eq, cal),--int8数值密文,确定性加密+同态加密
|
||
discount_price int8 encrypted(eq, cmp),--数值密文,确定性加密+保序加密
|
||
supplier_name varchar(255), --字符明文
|
||
supplier_address text
|
||
);
|
||
|
||
--插入数据
|
||
INSERT INTO sample_table VALUES
|
||
(1, '2024-03-29', 'Product_1', 'BMFTOEKLWR', 10000, 2000, 1699, 'Supplier_1', '2 Road, District_9'),
|
||
(2, '2023-12-27', 'Product_2', 'AZZPSNNNHP', 20000, 1000, 890, 'Supplier_2', '7 Road, District_6'),
|
||
(3, '2020-03-13', 'Product_2', 'RJBVWGLNMK', 22500, 599, 469, 'Supplier_3', '1 Road, District_4'),
|
||
(4, '2020-04-21', 'Product_2', 'QLLCNGBDSV', 20000, 1200, 1099, 'Supplier_3', '1 Road, District_4'),
|
||
(5, '2020-01-10', 'Product_3', 'CPSLKAILDA', 5000, 2599, 2180, 'Supplier_2', '7 Road, District_6'),
|
||
(6, '2024-05-02', 'Product_3', 'WKGWZKTNSC', 15000, 1990, 1690, 'Supplier_4', '8 Road, District_2'),
|
||
(7, '2022-11-30', 'Product_4', 'PKDVPUEUEL', 6000, 5999, 5399, 'Supplier_3', '1 Road, District_4'),
|
||
(8, '2020-06-28', 'Product_5', 'ORXMPSQCQK', 2000, 4999, 4321, 'Supplier_1', '2 Road, District_9'),
|
||
(9, '2022-02-24', 'Product_6', 'CYKQRZFHTZ', 20, 18000, 16990, 'Supplier_5', '12 Road, District_3'),
|
||
(10, '2021-05-27', 'Product_7', 'NZJQYDWQCQ', 4000, 2700, 1688, 'Supplier_2', '7 Road, District_6');
|
||
|
||
SELECT * FROM sample_table;
|
||
```
|
||
|
||
---
|
||
|
||
#### 2. 常用密文SQL计算功能
|
||
|
||
```sql
|
||
--------------------------------常用SQL语句功能测试----------------------------------
|
||
--插入查询自动加解密(1.2.1)、明文功能正常使用(1.4.1)、密文标准SQL功能支持(1.4.4)
|
||
----------------逻辑运算(1.2.2)---------------
|
||
--等值运算(=, !=, GROUP BY)、比较运算(>, <, >=, <=, BETWEEN...AND, ORDER BY, 升序ASC, 降序DESC)、析取合取(AND, OR)等
|
||
--等值运算**仅支持在eq加密字段**密文上执行
|
||
--比较运算**仅支持在cmp加密字段**密文上执行
|
||
DELETE FROM sample_table WHERE id > 8;
|
||
UPDATE sample_table SET amount = 3000 WHERE datetime = '2020-06-28';
|
||
SELECT * FROM sample_table;
|
||
SELECT * FROM sample_table WHERE supplier_name != 'Supplier_3' OR discount_price>=5000;
|
||
SELECT * FROM sample_table WHERE name = 'Product_2' AND discount_price < 1000;
|
||
SELECT * FROM sample_table WHERE discount_price BETWEEN 1000 AND 3000;
|
||
SELECT * FROM sample_table WHERE discount_price > 1500 ORDER BY discount_price DESC;
|
||
SELECT name, COUNT(*) AS nums FROM sample_table GROUP BY name;
|
||
|
||
----------------数值运算(1.2.3)---------------
|
||
--数学运算(+, -, *)、聚合函数(MAX, MIN, SUM, COUNT, POW)、混合类型运算(1.2.6)等
|
||
SELECT price,price+100 AS add_100 FROM sample_table WHERE name = 'Product_3';
|
||
SELECT amount,price,amount*price AS total_price FROM sample_table WHERE name = 'Product_4';
|
||
--int4, int8类型混合运算
|
||
SELECT amount,price,price + amount AS test_value FROM sample_table WHERE name = 'Product_4';
|
||
SELECT MAX(discount_price) AS max_value FROM sample_table;
|
||
SELECT MIN(discount_price) AS min_value FROM sample_table;
|
||
SELECT SUM(amount) AS sum_of_amount FROM sample_table WHERE id < 6;
|
||
SELECT COUNT(name) AS count_name FROM sample_table WHERE supplier_address != '2 Road, District_9';
|
||
|
||
```
|
||
|
||
---
|
||
|
||
#### 3. 密文索引功能
|
||
|
||
```sql
|
||
----------------------------------密文索引测试部分-----------------------------------
|
||
--密文索引能力比对(1.2.5): 验证支持构建高效密文索引
|
||
--在大量数据下才有所体现,这里仅作为功能展示
|
||
|
||
--关闭全表扫描
|
||
SET enable_seqscan TO off;
|
||
--建立索引前查询情况
|
||
explain analyze SELECT * FROM sample_table WHERE discount_price < 2000;
|
||
--在discount_price保序密文列上建立索引
|
||
CREATE INDEX idx_discount_price on sample_table(discount_price);
|
||
--建立索引后查询情况
|
||
explain analyze SELECT * FROM sample_table WHERE discount_price < 2000;
|
||
|
||
--在name确定性密文列上建立索引
|
||
explain analyze SELECT * FROM sample_table WHERE name = 'Product_2';
|
||
CREATE INDEX idx_name on sample_table(name);
|
||
explain analyze SELECT * FROM sample_table WHERE name = 'Product_2';
|
||
|
||
```
|
||
|
||
---
|
||
|
||
#### 4. 密钥轮转功能
|
||
|
||
```sql
|
||
---------------------------------密钥轮转测试部分------------------------------------
|
||
--密钥轮转(1.3.2): 现阶段支持CMK手动轮转和自动轮转,DEK随之同步更新;
|
||
--支持DEK的手动轮转,表级DEK、列级DEK或两者均支持;
|
||
--密钥用途唯一性(1.3.7): CMK仅用于加密DEK, DEK仅用于加密数据
|
||
--创建新表生成新DEK
|
||
CREATE TABLE t1(id int encrypted(eq));
|
||
--用DEK加密插入数据
|
||
INSERT INTO t1 VALUES (10),(20),(30);
|
||
SELECT * FROM t1;
|
||
--手动轮转CMK命令,同步更新DEK信息(大小写均可)
|
||
rotate cmk now;
|
||
--更新DEK后查询正常解密数据
|
||
SELECT * FROM t1;
|
||
DROP TABLE t1;
|
||
|
||
--自动轮转CMK命令,cmk rotate/rotation on/off/status; 开启/关闭/查询自动轮转(大小写均可)
|
||
--开启CMK自动轮转
|
||
cmk rotate on;
|
||
--查询CMK自动轮转状态
|
||
cmk rotate status;
|
||
--关闭CMK自动轮转
|
||
cmk rotate off;
|
||
|
||
--通过/new_enc/kms_test/CMK_auto_rotate_status.json文件持久化保存
|
||
--退出psql重新连接后,状态仍保持
|
||
|
||
--USAGE: ROTATE DEK NOW <table_name> [OPTIONS];
|
||
--DESCRIPTION: 轮换指定表的数据加密密钥(DEK)
|
||
--OPTIONS:
|
||
--TK 仅轮换表密钥
|
||
--CK <cols> 轮换指定列密钥,多个列名用逗号分隔
|
||
--ALL 轮换所有密钥(表密钥+所有列密钥)
|
||
--EXAMPLES:
|
||
ROTATE DEK NOW users -TK;
|
||
ROTATE DEK NOW users -CK `name`,`email`;
|
||
ROTATE DEK NOW users -ALL;
|
||
```
|
||
|
||
---
|
||
|
||
#### 5. 列级密钥相关功能
|
||
|
||
现完成列密钥的create、insert、update、select语句:
|
||
|
||
+ eq\eqsm4\rnd后面加 _c即可表示使用列密钥,其他加密种类暂不支持
|
||
|
||
```sql
|
||
enc on;
|
||
|
||
-- CREATE TABLE
|
||
CREATE TABLE sample (
|
||
col1 decimal(10,2) encrypted(eq_c),
|
||
col2 text encrypted(rnd_c),
|
||
col3 text,
|
||
col4 decimal(10,2) encrypted(eqsm4_c),
|
||
col5 decimal(10,2) encrypted(eq,cmp,cal),
|
||
col6 decimal(10,2) encrypted(eq,cmp,cal)
|
||
);
|
||
|
||
-- 插入语句
|
||
INSERT INTO sample (col1, col2, col3, col4, col5, col6)
|
||
VALUES
|
||
(12.34, 'secret1', 'hello', 12.34, 90.12, 90.12),
|
||
(12.34, 'secret2', 'world', 12.34, 12.34, 12.34),
|
||
(12.34, 'secret3', 'nihao', 34.56, 34.56, 12.34),
|
||
(-0.1234567890, 'secret4', 'world', 99.9999999999, 11.1111111111, 22.2222222222);
|
||
```
|
||
|
||
---
|
||
|
||
#### 6. 密钥查询功能
|
||
|
||
现完成密钥查询功能,提供查询CMK明密文的功能;
|
||
输出username、cmk_data、rotate_period、is_primary_version、is_rotated信息;
|
||
(DEK无感使用,不提供查询接口):
|
||
|
||
```sql
|
||
enc on;
|
||
|
||
--查询CMK密文
|
||
describe cmk;
|
||
|
||
--查询CMK明文(解密后)
|
||
describe cmk -d;
|
||
-- 或
|
||
describe cmk -decrypt;
|
||
```
|
||
|
||
---
|
||
|
||
#### 7. 数据脱敏功能
|
||
|
||
现新增数据脱敏函数,函数集合在`mask_funcs.sql` 文件中;
|
||
|
||
+ 所有函数**统一返回**`text`**类型**,NULL值返回NULL值
|
||
+ 默认是缺省规则(保留前a位和后b位)
|
||
+ UDF函数**明密文状态下均可使用**
|
||
+ `insert`插入时脱敏(**静态脱敏**),`select`查询时脱敏(**动态脱敏**)
|
||
|
||
- 也可`update`更新脱敏数据状态
|
||
|
||
具体函数如下:
|
||
|
||
```sql
|
||
SELECT mask('abcdefg', 2, 2) AS default, --缺省规则(前a后b)
|
||
mask_name('张三丰') AS name_cn, --中文名(后1)
|
||
mask_name('John Doe') AS name_en, --英文名(前1)
|
||
mask_nick('小海浪子') AS nick, --昵称(前1后1)
|
||
mask_email('bob@example.com') AS email, --邮箱(@后)
|
||
mask_mobile('13812345678') AS mobile, --手机号(前3后2)
|
||
mask_tel('010-88889999') AS tel, --固定电话(后2)
|
||
mask_idcard('11010519900307563X') AS idcard, --身份证号(前1后1)
|
||
mask_bankcard('6225888812345678') AS bank, --银行卡号(前4后4)
|
||
mask_plate('浙A12345') AS plate, --车牌(前2后2)
|
||
mask_ip('192.168.1.100') AS ip, --ip地址(前1字段)
|
||
mask_numeric(123.456) AS num, --数值取整(四舍五入)
|
||
mask_blank('anything') AS blank, --置空(直接替换为-)
|
||
mask_full('top secret') AS full; --全遮(保留长度,全替换为*)
|
||
|
||
|
||
--输出效果如下:
|
||
name_cn | name_en | nick | email |
|
||
---------+----------+------+---------------------+
|
||
**丰 | J******* | 小*子 | *****@example.com |
|
||
|
||
mobile | tel | idcard |
|
||
------------+------------+-------------------+
|
||
138*****78 | ********99 | 1****************X |
|
||
|
||
bank | plate | ip |
|
||
----------------------+----------+-----------+
|
||
6225************5678 | 浙A***45 | 192.*.*.* |
|
||
|
||
num | blank | def | full
|
||
------+-------+---------+-----------
|
||
123 | - | ab***fg | **********
|
||
|
||
```
|
||
|
||
+ 可在密态数据库中通过输入语句:
|
||
|
||
```sql
|
||
\i ../mask_funcs.sql
|
||
```
|
||
|
||
执行文件编写UDF;
|
||
|
||
+ 也可以在进入psql界面之前,通过输入命令:
|
||
|
||
```bash
|
||
psql -f mask_funcs.sql
|
||
```
|
||
|
||
纳入版本库部署;
|
||
|
||
使用**静态脱敏**时,可在`insert` 时**直接调用函数**,例如:
|
||
|
||
```sql
|
||
CREATE TABLE customer (mobile text, email text);
|
||
|
||
INSERT INTO customer (mobile, email)
|
||
VALUES (mask_mobile('13812345678'),
|
||
mask_email('alice@example.com'));
|
||
|
||
SELECT * FROM customer;
|
||
```
|
||
|
||
+ 若客户端 SQL 里不能显式写函数,可在**在 BEFORE INSERT 触发器里改写 NEW 值**统一处理,让客户端原样插入明文,由数据库自动脱敏后落盘,例:
|
||
|
||
```sql
|
||
CREATE OR REPLACE FUNCTION trg_mask_customer()
|
||
RETURNS trigger
|
||
LANGUAGE plpgsql AS
|
||
$$
|
||
BEGIN
|
||
NEW.mobile := mask_mobile(NEW.mobile);
|
||
NEW.email := mask_email(NEW.email);
|
||
RETURN NEW;
|
||
END;
|
||
$$;
|
||
|
||
CREATE TRIGGER bi_customer
|
||
BEFORE INSERT ON customer
|
||
FOR EACH ROW
|
||
EXECUTE FUNCTION trg_mask_customer();
|
||
```
|
||
|
||
+ 客户端照旧 `INSERT INTO customer(mobile,email) VALUES('13812345678','alice@example.com');`,触发器会把列值替换成脱敏后的结果再写入.
|
||
|
||
使用**动态脱敏**时,通过生成列 / 视图,既保存原文又随时提供脱敏视图,
|
||
|
||
- 原数据写入真实列
|
||
|
||
- 建视图或在 SELECT 时调用脱敏函数,例:
|
||
|
||
```sql
|
||
CREATE VIEW v_customer AS
|
||
SELECT id,
|
||
mask_name(name) AS name,
|
||
mask_mobile(mobile) AS mobile,
|
||
mask_email(email) AS email
|
||
FROM customer;
|
||
```
|
||
|
||
# 备份命令
|
||
su root
|
||
/usr/local/postgresql/bin/backup postgres
|
||
|
||
# 导入命令
|
||
su root
|
||
/usr/local/postgresql/bin/restore postgres
|
||
|