【问题标题】:SQLSERVER: BCP import and encrypt columns using Database KeySQL SERVER:BCP 使用数据库密钥导入和加密列
【发布时间】:2020-08-27 00:07:42
【问题描述】:

我有一个需要导入 SQL Server 的大文件。文件包含个人信息列(如 first_name、phone_number)。目前我正在使用 BCP 工具将大文件导入 SQL Server。下一步,我将使用数据库密钥对列进行加密,如下所示。

CREATE TABLE users (
    first_name VARCHAR(4000)
)

CREATE CERTIFICATE db_cert1
WITH SUBJECT = 'Encrypt PII data'; 
GO 

CREATE SYMMETRIC KEY db_symkey1
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE db_cert1;
GO

BEGIN TRY
    UPDATE users
    SET first_name = CAST(EncryptByKey(KEY_GUID('db_symkey1'),[first_name]) AS VARCHAR(MAX))
END TRY
BEGIN CATCH
    DELETE FROM users;
END CATCH

我的表中有 100 列和 10 列需要加密和数百万行的敏感列。目前它很慢(由于行数和 VARCHAR(MAX/4000))

有没有更好的方法来实现这一点? BCP 是否提供开箱即用的解决方案?

【问题讨论】:

    标签: sql-server database encryption import bcp


    【解决方案1】:

    我猜由于您的字段类型,您正在对nvarchar(max) 进行强制转换。改用varbinary 会更好。

    函数EncryptByKey返回:

    varbinary with a maximum size of 8,000 bytes.
    

    因此,以这种格式存储您的数据将不再需要强制转换。此外,最好为varbinary 长度使用精确值。

    您可以使用下面的公式来检查 EncryptByKey 将为特定文本列返回的最大 varbinary 长度:

    60 + max_length - ((max_length + 8) % 16) 
    

    我经常使用以下脚本:

    SELECT name,  60 + max_length - ((max_length + 8) % 16) 
    FROM sys.columns
    WHERE object_id = OBJECT_ID('dbo.securityUsers')
        AND name in ('FirstName', 'LastName', 'Gender', 'Address1', 'Address2', 'City', 'Province', 'Country')
    

    例如,对于nvarchar(128),您将拥有varbinary(308)。你只需要知道当你解密时,你需要再次转换为nvarchar(128)

    一般来说,尽量使用精度尽可能低的类型,并且也要尽可能地转换为最小精度。

    例如,您可以将这些数据插入到缓冲区表中,然后对其进行加密并将其记录在目标表中(无需转换)。

    【讨论】:

    • 感谢您的快速回复。有没有办法在一张桌子上处理这个?此外,将 first_name 作为 VARBINARY 的问题是我首先需要将文件按原样导入用户表,并且列必须是 VARCHAR(因为文件中的 first_name 是纯字符串)..
    • 是的,您需要分两步执行此操作。导入缓冲区表中的数据 - 然后加密数据并使用二进制列在目标表中插入/更新。好吧,您可以在一个表中包含 duplicate 列 - 例如,first_name_textfirst_name_encrypted - 将数据从第一列移动到第二列,然后 NULL 它,但这对我来说不是明确的解决方案。
    • 将遵循后一种方法(具有重复的列)以避免将数据从一个表传输到另一个表时的时间消耗。谢谢
    • 如果有速度优化,请告诉我:=)
    • 我已经添加了最终的步骤列表作为下面的答案
    【解决方案2】:

    以下是提高性能所遵循的步骤。

    1. 为每个敏感数据创建了两列
      • first_name_plaintext VARCHAR(256)
      • first_name VARBINARY(308)
      • 感谢@gotqn
    2. 添加了一个自动递增的 id 列,在表上添加了一个聚集索引(这确保它已经排序)并进行了批量更新(如 WHERE [id] BETWEEN 1 AND 100000)。
    3. 每次迭代后提交(以减少事务日志的使用)
    4. 将数据库恢复模式更改为简单(重要)
    5. 增加了 DB 文件大小
    6. 如果没有限制,您可以使用 AES_128 加密代替 AES_256 来创建密钥,但我们的安全顾问不允许这样做。

    这将 100 万条记录的时间从 3 分钟缩短到 1:17 分钟。

    【讨论】:

      猜你喜欢
      • 2023-02-01
      • 2013-01-02
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多