ByteHouse 云数仓版支持数据透明加密功能,为整表或按列进行数据加密,强化核心数据安全,满足您的监管和合规需求。本文将介绍 ByteHouse 的加密机制以及如何在 ByteHouse 中使用数据加密。
使用限制
- 该功能为 Beta 功能,如需使用,请提交工单或联系 ByteHouse 团队获取白名单权限。
- 仅主账号或具有 AccountAdmin、SystemAdmin 角色且拥有 ByteHouse 控制台访问权限的子账号可开启 ByteHouse 数据加密功能。
注意事项
- 开启 ByteHouse 数据加密后,由于数据处理过程中会涉及加密和解密操作,表性能会有 10%+ 的损失。
- ByteHouse 数据加密功能开启后不支持关闭,请谨慎操作。如果您希望不再对表/列继续加密,可参考修改加密表、加密列,调整表/列的配置,无需关闭 ByteHouse 数据加密功能。
- 开启 ByteHouse 数据加密后,数据加密功能依赖的火山引擎密钥管理服务 KMS 将开始计费,请勿关闭火山引擎 KMS 服务、欠费或删除 ByteHouse 相关的密钥,否则将导致数据读写错误。如计划不再使用该服务,请先联系 ByteHouse 团队沟通,避免出现已加密数据无法使用的问题。
- 请确保您使用的火山引擎密钥管理服务与 ByteHouse 云数仓服务处于同一地域。
功能概述
ByteHouse 依托火山引擎密钥管理服务 KMS(Key Management Service),并整合 ClickHouse 社区的表级和列级加密机制,实现数据透明加密存储,以保护底层静态数据。数据库透明加密是指您向 ByteHouse 写入数据时进行加密,在您查询数据时,会将数据自动解密并返回结果。使用 KMS 对 ByteHouse 进行密钥管理时,密钥层次结构包括了用户主密钥(CMK)和数据加密密钥(DEK)。整体加解密流程如下:
- 用户在 KMS 服务中创建主密钥,通过 CMK 生成数据密钥(DEK 明文和密文)。
- DEK 明文密钥对明文数据进行加密,生成密文数据,将数据密钥密文和加密后数据持久化保存。
- 数据读取时,如果系统发现数据已加密,则基于数据块中的数据密钥密文,向 CMK 请求数据密钥明文,再对数据密文进行解密,并将解密后的数据返回给用户。解密过程无需用户干预,由系统自动完成。

具体数据加密机制如下:
- ByteHouse 采用透明加密方式,支持 AES-128-GCM-SIV 和 AES-256-GCM-SIV 加密算法。
- 使用时,需先开启火山引擎 KMS 服务和 ByteHouse 数据加密功能,再通过 SQL 命令(DDL)为数据表/列开启加密并配置加密参数;完成配置后,数据在写入时会自动加密,查询时会自动解密,无需在后续操作中手动处理密钥或加密逻辑,不影响日常数据读写习惯。
- 火山引擎 KMS 服务支持 KMS 服务派生的密钥以及自带密钥(Bring Your Own Key,BYOK),您可以通过火山引擎 KMS 创建密钥,并在 ByteHouse 中启用 KMS 服务用于数据加密。在使用数据加密功能前,请确保您所在区域已开通 KMS 服务,操作指南请参见密钥管理快速入门。
- ByteHouse 以表和列为单位,通过 KMS 加密或解密存储在 ByteHouse 的数据。
- 在火山引擎 KMS 上创建用户密钥环(CustomKeyring)后,将使用 KMS 托管服务,同时,在数据执行读写操作时,ByteHouse 会调用 KMS 的 API 获取相关的密钥信息,因此在使用数据加密功能时会产生相关的 KMS 费用。KMS 相关计费说明请参见 KMS 计费说明。如果您在火山引擎 KMS 创建的密钥环类型为云服务托管密钥环(ManagedKeyring),火山引擎将仅收取 API 调用费用,相关托管费用将由创建密钥的云服务承担,实际计费请以您所使用服务的计费规则为准。
开启数据加密功能
- 开通 ByteHouse 数据加密服务依赖的火山引擎 KMS 服务。
登录 ByteHouse 云数仓控制台,在租户管理 > 数据加密页面中,单击第 1 步中的去开通 KMS,系统将跳转至火山引擎 KMS 服务开通页面,您可参考密钥管理快速入门开通并配置火山引擎 KMS 服务。开通时,请确保您使用的 KMS 服务与 ByteHouse 处于同一地域。
开通完成后,请返回 ByteHouse 云数仓控制台,查看流程引导中的开通 KMS 服务是否显示已开通。

- 单击第 2 步中的立即开启,开启 ByteHouse 数据加密功能。请仔细阅读弹出的提示后,单击确定。

- 当页面提示“已开启数据加密”时,表示功能正常开启,如下图。

使用数据加密
ByteHouse 支持通过 SQL 命令开启表/列加密。您可创建加密表/列,也可通过命令将存量非加密表/列为加密表/列。对于存在历史数据的表,开启加密后,仅支持对新写入的数据加密。
创建加密表/列
创建表时,可以使用以下参数设置整表/列加密:
- 加密表:将 setting 参数
encrypt_table 设置为 1,表示开启表加密,即 SETTINGS encrypt_table=1。 - 加密列:可通过 AES_128_GCM_SIV 或 AES_256_GCM_SIV 算法加密。例如,在对应的列设置
Codec(LZ4, AES_256_GCM_SIV) 参数,表示Codec 参数由压缩算法(LZ4)和加密算法(AES_256_GCM_SIV)组成。
示例 1:创建加密表
执行该命令后,目标表将开启整表加密,后续写入的数据会自动加密。使用时请将表名替换为您实际的表名。
CREATE TABLE test.new_encrypted_table
(
`A` Int64
)
ENGINE = CnchMergeTree()
ORDER BY A
SETTINGS encrypt_table=1
示例 2:创建加密列
执行该命令后,系统将为目标列加密,后续写入该列的数据会自动加密。使用时请将表名、列名替换为您实际的表名和列名。
CREATE TABLE test.new_encrypted_column_table
(
`A` Int64 Codec(LZ4, AES_256_GCM_SIV)
)
ENGINE = CnchMergeTree()
ORDER BY A
修改加密表、加密列
对于存量数据表,可以通过 Alter table... MODIFY... 设置数据加密:
- 加密表:将 setting 参数
encrypt_table 设置为 1,表示开启表加密,即 SETTINGS encrypt_table=1。设置为 0 表示取消加密。 - 加密列:可通过 AES_128_GCM_SIV 或 AES_256_GCM_SIV 算法加密,例如,在对应的列设置
Codec(LZ4, AES_256_GCM_SIV) 参数,表示Codec 参数由压缩算法(LZ4)和加密算法(AES_256_GCM_SIV)组成。
示例 1:将非加密表改为加密表
执行该命令后,该表将开启整表加密,新写入的数据会自动加密,历史数据不会加密。使用时请将表名替换为您实际的表名。
ALTER TABLE test.new_encrypted_table
MODIFY SETTING encrypt_table=1;
示例 2:将非加密列改为加密列
执行该命令后,系统将为目标列加密,新写入的数据库会自动加密,历史数据不会加密。使用时请将表名、列名替换为您实际的表名和列名。
ALTER TABLE test.new_encrypted_column_table
MODIFY COLUMN A Codec(LZ4, AES_256_GCM_SIV)
示例 3:将加密表改为非加密表
执行该命令后,该列取消加密,新写入的数据不再加密,历史已加密的数据将保持加密状态。使用时请将表名、列名替换为您实际的表名和列名。
ALTER TABLE test.new_encrypted_table
MODIFY SETTING encrypt_table=0;
示例 4:将加密列改为非加密列
执行该命令后,该列取消加密,新写入的数据不再加密,历史已加密的数据将保持加密状态。使用时请将表名、列名替换为您实际的表名和列名。
ALTER TABLE test.new_encrypted_column_table
MODIFY COLUMN A Int64 REMOVE CODEC