encryption - Big Query 中的字段级加密
问题描述
我们的团队目前正在探索在 BigQuery 中在字段级别加密 PII 数据的方法,我们发现了以下使用Crypto-JS加密/解密的方法:
#standardSQL
CREATE TEMPORARY FUNCTION encrypt(_text STRING) RETURNS STRING LANGUAGE js AS
"""
let key = CryptoJS.enc.Utf8.parse("<key>");
let options = { iv: CryptoJS.enc.Utf8.parse("<iv>"), mode: CryptoJS.mode.CBC };
let _encrypt = CryptoJS.AES.encrypt(_text, key, options);
return _encrypt;
""";
CREATE TEMPORARY FUNCTION decrypt(_text STRING) RETURNS STRING LANGUAGE js AS
"""
let key = CryptoJS.enc.Utf8.parse("<key>");
let options = { iv: CryptoJS.enc.Utf8.parse("<iv>"), mode: CryptoJS.mode.CBC };
let _decrypt = CryptoJS.AES.decrypt(_text, key, options).toString(CryptoJS.enc.Utf8);
return _decrypt;
""" OPTIONS (library="gs://path/to/Crypto-JS/crypto-js.js");
-- query to encrypt fields
SELECT
<fields>, encrypt(<pii-fields>)
FROM
`<project>.<dataset>.<table>`
-- query to decrypt fields
SELECT
<fields>, decrypt(<pii-fields>)
FROM
`<project>.<dataset>.<table>`
我正在尝试在大查询中使用 Crypto JS 库对 AES CBC 加密和解密的性能进行基准测试,然后再将其部署到我们的生产中。我们发现,与通常的查询相比,随着数据数量的增加,每条记录的数据加密和解密速率呈指数增长。然而,随着要处理的数据数量的增加,每条记录的处理进度和记录处理时间正在改善。
由于没有关于此的可用文档,社区中的某个人是否可以帮助提供更好的方法、优化查询、在大查询中使用字段级加密和解密的最佳实践?
解决方案
BigQuery 现在支持加密功能。从文档中,这是一个独立的示例,它创建了一些密钥集并使用它们来加密数据。在实践中,您可能希望将密钥集存储在真实表中,以便以后可以使用它们来解密密文。
WITH CustomerKeysets AS (
SELECT 1 AS customer_id, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset UNION ALL
SELECT 2, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') UNION ALL
SELECT 3, KEYS.NEW_KEYSET('AEAD_AES_GCM_256')
), PlaintextCustomerData AS (
SELECT 1 AS customer_id, 'elephant' AS favorite_animal UNION ALL
SELECT 2, 'walrus' UNION ALL
SELECT 3, 'leopard'
)
SELECT
pcd.customer_id,
AEAD.ENCRYPT(
(SELECT keyset
FROM CustomerKeysets AS ck
WHERE ck.customer_id = pcd.customer_id),
pcd.favorite_animal,
CAST(pcd.customer_id AS STRING)
) AS encrypted_animal
FROM PlaintextCustomerData AS pcd;
编辑:如果您想使用带有 PKCS 填充的 AES-CBC 进行解密(不清楚您在示例中使用的是哪种填充),您可以使用该KEYS.ADD_KEY_FROM_RAW_BYTES
函数创建密钥集,然后调用AEAD.DECRYPT_STRING
或AEAD.DECRYPT_BYTES
. 例如:
SELECT
AEAD.DECRYPT_STRING(
KEYS.ADD_KEY_FROM_RAW_BYTES(b'', 'AES_CBC_PKCS', b'1234567890123456'),
FROM_HEX('deed2a88e73dccaa30a9e6e296f62be27db30db16f76d3f42c85d31db3f46376'),
'')
这返回abcdef
。IV 预计是密文的前 16 个字节。
推荐阅读
- swift - 您将如何在 swiftUI/Swift 的滑块轨道中绘制节点?
- java - 下载的 Selenium jar 中没有 java 类
- python - 我收到这个错误。找不到页面 (404) 请求方法:GET 请求 URL:http://127.0.0.1:8000/polls/
- python - 在 Python 中将列表作为参数
- mysql - How to combine 3 tables having same column names in MySQL?
- android-studio - 颤振已经安装!但仍然显示“未安装 Flutter 插件;这增加了 Flutter 特定的功能”
- java - Gradle无法在java项目中复制png文件
- javascript - 单击链接将活动类添加到导航菜单
- laravel - 如何从一个表中获取 Laravel 5.8 中另一个表中不存在的所有记录
- sql - Oracle 字母数字序列