Шифрование на уровне поля в большом запросе - PullRequest
0 голосов
/ 13 ноября 2018

Наша команда в настоящее время изучает способы шифрования данных PII на уровне поля в BigQuery, и мы нашли следующий способ шифрования / дешифрования с использованием 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>`

Я пытаюсь оценить производительность шифрования и дешифрования AES CBC с помощью библиотеки Crypto JS в большом запросе перед его развертыванием в нашей рабочей среде. Мы обнаружили, что скорость шифрования и дешифрования данных растет экспоненциально для каждой записи с увеличением количества данных по сравнению с обычным запросом. Однако с увеличением количества обрабатываемых данных прогресс в обработке на одну запись и время обработки записи улучшается.

Поскольку нет доступной документации по этому вопросу, может ли кто-нибудь из сообщества помочь предоставить более эффективные способы, оптимизировать запрос, рекомендации по использованию шифрования и дешифрования на уровне поля в большом запросе?

enter image description here

1 Ответ

0 голосов
/ 12 апреля 2019

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;

Редактировать: если вы хотите расшифровать, используя AES-CBC с заполнением PKCS (неясно, какой тип заполнения вы используете в вашем примере), вы можете использовать функцию 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 байтом зашифрованного текста.

...