標準 SQL 中的 AEAD 加密函式

以下各節說明 BigQuery 支援的 AEAD 加密函式。如需 AEAD 加密函式的運作說明,請參閱 AEAD 加密概念一文。

KEYS.NEW_KEYSET

KEYS.NEW_KEYSET(key_type)

說明

根據 key_type 傳回包含新金鑰的序列化金鑰組。傳回的金鑰組是下列項目的序列化 BYTES 表示法:google.crypto.tink.Keyset,該項目包含主要加密編譯金鑰,且沒有其他金鑰。您可以將金鑰組與 AEAD.ENCRYPTAEAD.DECRYPT_BYTESAEAD.DECRYPT_STRING 函式搭配使用來進行加密與解密,也可以與金鑰和金鑰組相關函式的 KEYS 群組搭配使用。

key_type 是要建立的金鑰類型的 STRING 文字表示法。key_type 不得為 NULLkey_type 唯一支援的值是目前的 AEAD_AES_GCM_256KEYS.NEW_KEYSET(AEAD_AES_GCM_256) 會使用 OpenSSL 提供的虛擬隨機號碼產生器建立 256 位元金鑰。金鑰將使用 AES-GCM 執行加密及解密作業。

傳回資料類型

BYTES

範例

以下查詢會針對 CustomerIds 中的每個資料列建立金鑰組,您之後可使用該金鑰組加密資料。每個金鑰組都包含一個加密金鑰和隨機產生的金鑰資料。輸出結果中每個資料列都包含 customer_id 和以 BYTES 表示的 'AEAD_AES_GCM_256' 金鑰。

SELECT customer_id, KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset
FROM (
  SELECT 1 AS customer_id UNION ALL
  SELECT 2 UNION ALL
  SELECT 3
) AS CustomerIds;

KEYS.ADD_KEY_FROM_RAW_BYTES

KEYS.ADD_KEY_FROM_RAW_BYTES(keyset, key_type, raw_key_bytes)

說明

根據 key_typeraw_key_bytesBYTES 傳回序列化金鑰組,並將金鑰新增至 keyset

主要加密編譯金鑰會保持與 keyset 中的金鑰相同。raw_key_bytes 的預期長度取決於 key_type 的值。以下是支援的 key_types

  • 'AES_CBC_PKCS':使用加密區塊鏈結和 PKCS 填充演算法,針對 AES 解密建立金鑰。raw_key_bytes 預期是長度為 16、24 或 32 的原始金鑰 BYTES 值;這些長度的大小分別為 128、192 和 256 位元。BigQuery AEAD 函式不支援使用這些類型的金鑰進行加密,建議改用 'AEAD_AES_GCM_256''AES_GCM' 金鑰。

  • 'AES_GCM':使用 Galois/計數器模式,針對 AES 解密或加密建立金鑰。 raw_key_bytes 必須是長度為 16 或 32 的原始金鑰 BYTES 值;這些長度的大小分別為 128 和 256 位元。如果這個類型的金鑰是 AEAD.ENCRYPT 的輸入值,則輸出密文沒有 Tink 專屬的前置字串,指出做為輸入值使用的金鑰。

傳回資料類型

BYTES

範例

下列查詢可建立客戶 ID 與原始金鑰位元組的資料表 (稱為 CustomerRawKeys),以及唯一識別碼的資料表 (稱為 CustomerIds)。該查詢會為每個 customer_id 建立新的 'AEAD_AES_GCM_256' 金鑰組,然後會使用該 customer_id 對應的 raw_key_bytes 值,將金鑰新增至每個金鑰組。輸出結果是一個資料表,其中每個資料列都包含 customer_id 和以 BYTES 表示的金鑰組,且該金鑰組包含使用 KEYS.ADD_KEY_FROM_RAW_BYTES 新增的原始金鑰。

WITH CustomerRawKeys AS (
  SELECT 1 AS customer_id, b'0123456789012345' AS raw_key_bytes UNION ALL
  SELECT 2, b'9876543210543210' UNION ALL
  SELECT 3, b'0123012301230123'
), CustomerIds AS (
  SELECT 1 AS customer_id UNION ALL
  SELECT 2 UNION ALL
  SELECT 3
)
SELECT
  ci.customer_id,
  KEYS.ADD_KEY_FROM_RAW_BYTES(
    KEYS.NEW_KEYSET('AEAD_AES_GCM_256'),
    'AES_CBC_PKCS',
    (SELECT raw_key_bytes FROM CustomerRawKeys AS crk
     WHERE crk.customer_id = ci.customer_id)
  ) AS keyset
FROM CustomerIds AS ci;

每個輸出金鑰組都包含兩個項目:使用 KEYS.NEW_KEYSET('AEAD_AES_GCM_256') 建立的主要加密編譯金鑰,和使用 KEYS.ADD_KEY_FROM_RAW_BYTES 新增的原始金鑰。如果輸出結果中的金鑰組與 AEAD.ENCRYPT 搭配使用,BigQuery 會使用透過 KEYS.NEW_KEYSET('AEAD_AES_GCM_256') 建立的主要加密編譯金鑰來加密輸入明文。如果金鑰組與 AEAD.DECRYPT_STRINGAEAD.DECRYPT_BYTES 搭配使用,BigQuery 會在任一金鑰成功解密密文的情況下傳回產生的明文。

AEAD.DECRYPT_BYTES

AEAD.DECRYPT_BYTES(keyset, ciphertext, additional_data)

說明

使用 keyset 中的相符金鑰解密 ciphertext,並使用 additional_data 驗證資料的完整性。如果解密或驗證失敗,系統會傳回錯誤。

keyset 是其中一個 KEYS 函式傳回的序列化 BYTES 值。keyset 必須包含用於加密 ciphertext 的金鑰,且金鑰必須處於 'ENABLED' 狀態,否則,函式會傳回錯誤。AEAD.DECRYPT_BYTES 可透過尋找金鑰 ID 與在 ciphertext 中加密的金鑰 ID 相符的金鑰,來識別 keyset 中的相符金鑰。

ciphertext 是呼叫 AEAD.ENCRYPT 而產生的 BYTES 值,其輸入 plaintext 的類型為 BYTES

additional_dataSTRINGBYTES 值,可確保加密資料的真實性和完整性。此函式會將任何 STRING 值轉換成 BYTES。此值必須與提供給 AEAD.ENCRYPTadditional_data 相同,才能加密 ciphertext,進而忽略其類型,否則,函式會傳回錯誤。

傳回資料類型

BYTES

範例

此範例會建立唯一識別碼及相關明文值和金鑰組的資料表,然後使用這些金鑰組以 BYTES 形式加密明文值,並將其儲存在新資料表中,最後再使用 AEAD.DECRYPT_BYTES 解密已加密的值,並將其顯示為明文。

下列陳述式會建立資料表 CustomerKeysets,其中包含唯一識別碼資料欄、AEAD_AES_GCM_256 金鑰組資料欄以及最喜愛的動物資料欄。

CREATE TABLE aead.CustomerKeysets AS
SELECT
  1 AS customer_id,
  KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset,
  'jaguar' AS favorite_animal
UNION ALL
SELECT
  2 AS customer_id,
  KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset,
  'zebra' AS favorite_animal
UNION ALL
SELECT
  3 AS customer_id,
  KEYS.NEW_KEYSET('AEAD_AES_GCM_256') AS keyset,
  'nautilus' AS favorite_animal;

下列陳述式會建立資料表 EncryptedCustomerData,其中包含唯一識別碼資料欄和密文資料欄。陳述式會使用每個唯一識別碼對應的 CustomerKeysets 中的金鑰組值,加密明文 favorite_animal

CREATE TABLE aead.EncryptedCustomerData AS
SELECT
  customer_id,
  AEAD.ENCRYPT(keyset, favorite_animal, CAST(customer_id AS STRING))
   AS encrypted_animal
FROM
  aead.CustomerKeysets AS ck;

以下查詢會使用 CustomerKeysets 資料表中的金鑰組來解密 EncryptedCustomerData 資料表中的資料。

SELECT
  ecd.customer_id,
  AEAD.DECRYPT_STRING(
    (SELECT ck.keyset
     FROM aead.CustomerKeysets AS ck
     WHERE ecd.customer_id = ck.customer_id),
    ecd.encrypted_animal,
    CAST(ecd.customer_id AS STRING)
  ) AS favorite_animal
FROM aead.EncryptedCustomerData AS ecd;

AEAD.DECRYPT_STRING

AEAD.DECRYPT_STRING(keyset, ciphertext, additional_data)

說明

就像 AEAD.DECRYPT_BYTES 一樣,但是 ciphertextAEAD.ENCRYPTBYTES 輸出值,其中 AEAD.ENCRYPTplaintext 輸入值是 STRING 類型,而不是 BYTES 類型。

傳回資料類型

STRING

AEAD.ENCRYPT

AEAD.ENCRYPT(keyset, plaintext, additional_data)

說明

使用演算法和主要加密編譯金鑰,以 keyset 加密明文。將 additional_data 整合到傳回的密文中。如果任何輸入值為 NULL,則傳回 NULL

keyset 是其中一個 KEYS 函式傳回的序列化 BYTES 值。

plaintext 是要加密的 STRINGBYTES 值。

additional_data 是要整合到已傳回密文的 STRINGBYTES 值。plaintextadditional_data 的類型必須相同。 AEAD.ENCRYPT(keyset, string1, string2) 等同於 AEAD.ENCRYPT(keyset, CAST(string1 AS BYTES), CAST(string2 AS BYTES))

輸出值為密文 BYTES。密文會包含 Tink 專屬的前置字串,指出用來執行加密的金鑰,但金鑰為 'AES_GCM' 金鑰時除外。

傳回資料類型

BYTES

範例

以下查詢使用 CustomerKeysets 資料表中每個 customer_id 的金鑰組,加密該 customer_id 對應 PlaintextCustomerData 資料表中的明文 favorite_animal 值。輸出結果包含 customer_id 值的資料欄和以 BYTES 表示的對應密文輸出值的資料欄。

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;

KEYS.KEYSET_FROM_JSON

KEYS.KEYSET_FROM_JSON(json_keyset)

說明

傳回輸入值 json_keyset STRING 做為序列化 BYTES,這是其他 KEYSAEAD 函式的有效輸入值。JSON STRING 必須與 google.crypto.tink.Keyset 通訊協定緩衝區訊息的定義相容:JSON 金鑰組應為 JSON 物件,且包含的物件和名稱-值組合應對應至 google.crypto.tink.Keyset 定義的「keyset」訊息中的物件和名稱-值組合。您可以使用 KEYS.KEYSET_TO_JSON 將輸出序列化 BYTES 表示法轉換回 JSON STRING

傳回資料類型

BYTES

範例

KEYS.KEYSET_FROM_JSON 會取用下列 JSON 格式的 STRING 值:

{
  "key":[
      {
        "keyData":{
          "keyMaterialType":"SYMMETRIC",
          "typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey",
          "value":"GiD80Z8kL6AP3iSNHhqseZGAIvq7TVQzClT7FQy8YwK3OQ=="
        },
        "keyId":3101427138,
        "outputPrefixType":"TINK",
        "status":"ENABLED"
      }
    ],
  "primaryKeyId":3101427138
}

以下查詢會利用 JSON 格式的 STRING json_keyset 建立新金鑰組:

SELECT KEYS.KEYSET_FROM_JSON(json_keyset);

這會傳回下列序列化為 BYTESjson_keyset

\x08\x9d\x8e\x85\x82\x09\x12d\x0aX\x0a0
type.googleapis.com/google.crypto.tink.AesGcmKey\x12\"\x1a qX\xe4IG\x87\x1f\xde
\xe3)+e\x98\x0a\x1c}\xfe\x88<\x12\xeb\xc1t\xb8\x83\x1a\xcd\xa8\x97\x84g\x18\x01
\x10\x01\x18\x9d\x8e\x85\x82\x09 \x01

KEYS.KEYSET_TO_JSON

KEYS.KEYSET_TO_JSON(keyset)

說明

傳回輸入值 keyset 的 JSON STRING 表示法。傳回的 JSON STRING 必須與 google.crypto.tink.Keyset 通訊協定緩衝區訊息的定義相容。您可以使用 KEYS.KEYSET_FROM_JSON 將 JSON STRING 表示法轉換回 BYTES

傳回資料類型

STRING

範例

以下查詢會以 JSON 格式的 STRING 傳回新 'AEAD_AES_GCM_256' 金鑰組。

SELECT KEYS.KEYSET_TO_JSON(KEYS.NEW_KEYSET('AEAD_AES_GCM_256'));

結果為下列 STRING

{
  "key":[
      {
        "keyData":{
          "keyMaterialType":"SYMMETRIC",
          "typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey",
          "value":"GiD80Z8kL6AP3iSNHhqseZGAIvq7TVQzClT7FQy8YwK3OQ=="
        },
        "keyId":3101427138,
        "outputPrefixType":"TINK",
        "status":"ENABLED"
      }
    ],
  "primaryKeyId":3101427138
}

KEYS.ROTATE_KEYSET

KEYS.ROTATE_KEYSET(keyset, key_type)

說明

根據 key_type 將金鑰新增至 keyset。這個新金鑰會變為新金鑰組的主要加密編譯金鑰。傳回序列化為 BYTES 的新金鑰組。

輸入值 keyset 中的舊主要加密編譯金鑰會將其他金鑰保留在傳回的金鑰組中。

傳回資料類型

BYTES

範例

下列陳述式會建立一個資料表,其中包含唯一 customer_id 值和 'AEAD_AES_GCM_256' 金鑰組的資料欄,然後會使用 KEYS.ROTATE_KEYSET,在來源資料表的每個金鑰組中建立新的主要加密編譯金鑰。輸出結果中的每個資料列都包含 customer_id 和以 BYTES 表示的 'AEAD_AES_GCM_256' 金鑰組。

WITH ExistingKeysets 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')
)
SELECT customer_id, KEYS.ROTATE_KEYSET(keyset, 'AEAD_AES_GCM_256') AS keyset
FROM ExistingKeysets;
本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁