ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

KingbaseES 数据加密全解:从 SSL 到全密态

KingbaseES 数据加密全解:从 SSL 到全密态 上个月跑等保客户那边管安全的人冷不丁问了我一句数据库文件要是被人整个端走你们怎么办我愣了一下。倒不是没想过而是突然发现平时聊数据库安全翻来覆去就是账号、权限、防火墙这些看门口的活儿。真到硬盘、备份磁带离开机房那一步——文件里的东西全是明文谁来都看得懂。这问题一下把我问住了。于是我把金仓官方知识库里安全与权限分类下的数据加密文档翻了个遍六篇从传输一路讲到代码加密。光看不过瘾又拉了台虚拟机一条条跑。本文就是那次折腾的流水账坑也没少踩一并写进来。四层楼各管各的先说整体感受。KingbaseES 的加密能力不是一锅炖更像一栋楼分四层住着四户人。一层管传输。SSL/TLS管的是报文在路上跑的时候别被人偷看。二层三层管存储一个粗一个细——表空间加密是粗网眼的渔网一捞一大片到了字段级别就换细筛子kbcrypto 和全密态都是干这个的。四层最特别它不管数据管代码数据库里那些函数、存储过程的源码也有专门的锁。四户互不干扰。你按合规要求挑着用就行。一层SSL/TLS明文传输这个事抓过一次包就忘不掉。客户端连数据库报文里都是赤裸裸的业务数据中间人看得一清二楚。SSL还有它的继任者 TLS干的就是给报文穿上衣服的活。KES 对这套的支持挺全尤其双向认证做得细——这词儿值得停下来说说。单向认证是客户端验服务器你真是那台服务器吗双向认证呢服务器反手也验一把客户端你手里有证书吗没有门都没有。也就是说密码被盗还不够攻击者还得连证书一起偷。再加上等保之类法规对传输加密有硬性要求。这事没什么好犹豫的做。配置的起点是证书。官方实验从搭 rootCA 开始我照着跑命令没几行# 根 CA 的私钥2048 位 rsaopenssl genrsa2048rootca.key# 自签名根证书。交互式提问一路回车即可openssl req-new-x509-nodes-days3600-keyrootca.key-outrootca.crt根证书有了该 KES 服务器出场。生成它的私钥和证书请求文件openssl req-newkeyrsa:2048-nodes-keyoutkesserver.key-outkesserver.csr说到这我必须交代一个自己踩的坑。生成 CSR 时会问你 Common Name我当时随手填了个主机别名。心想反正测试环境嘛。结果客户端拿 verify-full 模式一连校验失败。查了才知道这个字段会被拿来跟服务器名字对号。要么填服务器真名要么填*通配。之后证书发到服务端、客户端两边通道一开传输这块就算齐活了。二层表空间加密现在回答开头那个问题文件被拷走怎么办透明存储加密。具体到实现是 sysencrypt 这个插件。原理一句话内存里永远明文落盘那一刻加密读回内存那一刻解密。你在内存里查表、改数据、建索引跟普通表一模一样业务代码一个字不用动。页面为单位做块加密开销压在存储层性能损失不大——至少官方文档是这么说的我实测下来也确实感知不明显。密钥怎么管靠一个叫 TDE 钱包的东西。wallet 目录藏在集簇数据目录里跟数据文件分开放。三级密钥主密钥一把全局唯一管着下面的对象密钥每个加密对象一把对象密钥最后真正动手加密数据页的是从对象密钥加块标识派生的块级密钥。算法给了 SM4 和 RC4 两个。做密评就别犹豫SM4国密128 位分组 128 位密钥。开干前先装插件。kingbase.conf 里把 sysencrypt 加到 shared_preload_libraries重启建扩展shared_preload_libraries...,sysencrypt-- 重启后CREATEEXTENSION sysencrypt;然后是钱包。第一次用要设密码ALTERWALLETWITHPASSWORDSm4Wallet#2026;OPENUP WALLETWITHPASSWORDSm4Wallet#2026;打住这里插一句很重要的话。钱包密码忘了就是忘了。没有找回功能。钱包一丢加密数据永远是一堆乱码。这密码请多备份几处——写进你的密码管理器、打印一份锁抽屉里都行。钱包开了建加密表空间。两条路。手动派建的时候自己给密钥掌控感强。CREATETABLESPACEtbs_finance_enc LOCATION/home/kingbase/tbs_financeWITH(encryptiontrue,enckeySm4Fin#2026);enckey 上限 16 字节超了截断。里头至少一个数字一个字母单引号包着。不给也行系统替你生成。偷懒派把sysencrypt.encrypt_user_tablespace参数一开默认 off之后新建的用户表空间全部自动加密encryption true 都省了。哦对了这个参数关掉不影响存量——已经加密的表空间照样加密退不回明文除非删了重建。这点设计我觉得挺合理省得手一抖把生产库加密关了。加密有没有生效别信感觉翻磁盘最实在。加密表空间里建表、插几行、CHECKPOINT 落盘SELECT sys_relation_filepath(表名);拿到物理路径hexdump 一敲——满屏乱码。换默认表空间再来一遍hexdump 里明文字符串清清楚楚。这一对比比任何文档都有说服力。限制有三条记一下系统表空间和默认表空间不让加密只有自建的可以表空间加密跟表级加密互斥二选一不过字段类型、约束、索引它都不挑这点倒是省心。三层刀法由粗到细撒网式的表空间加密有个问题——太浪费。一张几百万行的用户表真正敏感的也许就身份证那一列为了它把整表都加密杀鸡用牛刀。所以还有三把更细的刀。一把比一把狠。第一把sysencrypt整表加密跟表空间加密同一个插件、同一套原理只是范围缩到单表。用法简单得出奇建表语句尾巴上加个词CREATETABLEcustomer_encrypted(idINTPRIMARYKEY,nameVARCHAR(50),id_cardVARCHAR(18),phoneVARCHAR(11),created_atTIMESTAMPDEFAULTNOW())ENCRYPTED;增删改查照旧。想知道表加密了没问数据库SELECTsysencrypt.is_table_encrypted(customer_encrypted);SELECT*FROMsysencrypt.sys_table_encryptWHEREtablenamecustomer_encrypted;hexdump 验证法照旧适用。但切换加密状态这件事我劝你慎重。ALTER TABLE ... ENCRYPTED或者反向的 NOT ENCRYPTED不是改个开关那么轻巧。数据库背后干的事是把整张表重建一遍先拿排他锁然后开新数据文件一行一行读出来、加密或解密、写回去改系统目录删旧文件。做完之后 sys_relation_filepath 给出的路径全变了——重建的痕迹。代价呢操作期间整表锁死谁也别想读写。新旧文件短暂并存磁盘得腾出一块等于原表大小的地方。大表跑起来又慢WAL 还哗哗地生成。所以——维护窗口测试环境先演练一样都不能省。第二把kbcrypto字段级国密整表加密还嫌粗上 kbcrypto。这插件默认就躺在 shared_preload_libraries 里建个扩展直接用。它给你的是一组显式调用的函数函数干什么用sm4(data, key, mode)SM4 加解密。mode 填 0 加密、1 解密参数是 BYTEAsm4_ex(data, key, mode, pad)多个填充模式1 按 16 字节倍数强制填0 非强制填 0x0sm3(data)SM3 摘要不可逆rc4(data, key, mode)RC4。用不用看你们的安全规范思路是应用自己说了算写入时加密读取时解密。身份证号、手机号这种字段密文直接用 BYTEA 存CREATETABLEstaff(idINTPRIMARYKEY,nameVARCHAR(50),id_card_encrypted BYTEA,phone_encrypted BYTEA);INSERTINTOstaffVALUES(1,王五,sm4(11010119900307663X::BYTEA,0123456789ABCDEF::BYTEA,0),sm4(13912345678::BYTEA,0123456789ABCDEF::BYTEA,0));SELECTid,name,convert_from(sm4(id_card_encrypted,0123456789ABCDEF::BYTEA,1),UTF8)ASid_card,convert_from(sm4(phone_encrypted,0123456789ABCDEF::BYTEA,1),UTF8)ASphoneFROMstaff;小坑记录这批函数吐的是二进制。终端显示成啥样看 bytea_output 参数默认 hex一串 \x 开头的十六进制看着眼晕。SET bytea_output TO escape;换转义格式。解密结果拿 convert_from 转回文本。还有密文字段建表就用 BYTEA别 TEXT 存完再折腾转换。密码字段走另一条路。密码不该可逆——SM3 出摘要存起来登录时把输入同样摘要一遍、比对。讲究点还得加盐加迭代。裸哈希高手面前撑不了几个回合。第三把kdb_ce 全密态前两把刀有个共同的软肋数据到了内存、进了查询执行终究是明文。DBA 想看拦不住。金融核心账户、医疗病历、高密级政务数据——这些场景的要求更过分连管理员都不许碰明文。kdb_ce 就是干这个的。名字叫全密态计算存储、传输、处理全程密文还能在密文上做一定范围的条件查询。怎么做到的双层密钥。客户端主密钥 CMK 放在你自己的本地 KMS 里它保护列加密密钥 CEKCEK 再加密列数据。数据库端只见过被包了一层的密钥材料和密文。明文密钥压根不出客户端。DBA 把库翻个底朝天也全是乱码。配置比前两个麻烦些。插件照挂 shared_preload_libraries、重启、建扩展之外还得设 LOCALKMS 环境变量、建密钥目录。另外客户端连接必须带 -M 参数进全密态模式——整条链路的关键开关少了它一切白搭CREATECLIENT MASTERKEYcmk_1WITH(KEY_STORELOCALKMS,KEY_PATHkms_1,ALGORITHMRSA_2048);CREATECOLUMNENCRYPTIONKEYcek_1WITHVALUES(CLIENT_MASTER_KEYcmk_1,ALGORITHMAEAD_AES_256_CBC_HMAC_SHA256);CREATETABLEcreditcard_info(id_numberINT,nameTEXTCLENCRYPTEDWITH(COLUMN_ENCRYPTION_KEYcek_1,ENCRYPTION_TYPEDETERMINISTIC),credit_cardVARCHAR(19)CLENCRYPTEDWITH(COLUMN_ENCRYPTION_KEYcek_1,ENCRYPTION_TYPEDETERMINISTIC));CLENCRYPTED 声明哪列加密。加密类型二选一得想清楚DETERMINISTIC确定性加密同明文永远同密文能做等值查询、能 JOIN代价是密文会泄露哪些行值相同这个规律RANDOMIZED同明文给不同密文更安全但等值匹配没戏。要进 WHERE 条件的列用前者只存不查的用后者。验证挺有意思。换个不带 -M 的普通连接查这张表——加密列全是乱码。翻数据文件乱码。抓包还是乱码。名不虚传。代价也得认部署、运维、性能三头都要花钱。给最核心的表用就好全库铺开没必要。四层锁代码数据护住了还有个东西容易漏——代码本身。存储过程、函数里写的都是业务逻辑。计费规则、风控口径全在系统目录里明晃晃摆着谁都能\sf一下看全文。合适吗未必。KingbaseES 拿系统自带的 DBMS_DDL 插件解决这事不用额外安装。函数就两个。WRAP 只管加密把你的 CREATE 语句吞进去吐回来一段加密文本至于执不执行你自己定。另一个 CREATE_WRAPPED 更省心加密加创建一次做完实操里大家基本都用它CALLdbms_ddl.CREATE_WRAPPED(q[ CREATE PROCEDURE getValue(pid int) AS BEGIN select now(); RAISE NOTICE pid%,pid; END ; ]);完了\sf getValue看一眼——函数体变成了AS WRAPPED加一长串 Base64 密文。逻辑一个字看不见。但调用一切正常CALL getValue(110);该输出输出。函数同理。怎么选四户人的差异粗粗一比就出来了。表空间加密管一大片sysencrypt 收缩到一张表kbcrypto 再收缩到一个字段kdb_ce 管得最绝——连 DBA 都别想看明文。改造量从零一路涨到要动 SQL性能代价也是全密态最贵。国密这边前三家都带 SM4kbcrypto 还能显式调 SM3全密态的示例走的是 AES-256 那套。选型我自己只归纳三条都很土。头一条想明白你要防的是谁。怕硬盘、备份流出去透明加密就行表空间级表级随你。怕的就几个字段泄露kbcrypto。要是连 DBA 都在你的防备名单里那没得挑kdb_ce。第二条算账。老系统要低成本上线透明加密几乎零改造这笔账怎么算都划算。第三条听测评方的。等保密评场合国密优先SM4、SM3 先用上最终口径以测评方为准自己拍脑袋定了也过不了审。最后折腾一圈我印象最深的反倒是另一件事这套体系每层都给你留了验货的口子。传输层可以抓包存储层直接 hexdump全密态拿不带 -M 的连接一查便知函数加密\sf一下就能看到密文。做安全不能凭感觉一层层亲手验过心里才有底。回头再答开头那个问题就一句话的事加密表空间加钱包。硬盘上躺着的全是密文被人端走也无非一堆乱码。要是 DBA 也在防备名单里那就再叠一层 kdb_ce。
返回列表