標準 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 不得為 NULL。目前唯一支援 key_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_bytes,傳回以 BYTES 表示的序列化金鑰組,並將金鑰新增至 keyset

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

  • 'AES_CBC_PKCS':使用加密區塊鏈結和 PKCS 填充演算法,針對 AES 解密建立金鑰。raw_key_bytes 必須是長度為 16、24 或 32 的原始金鑰 BYTES 值;這些長度的大小分別為 128 和 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 中加密金鑰相符的金鑰,來識別 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 定義中「金鑰組」訊息的物件和名稱/值組合相對應。您可以使用 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 STRINGgoogle.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;
本頁內容對您是否有任何幫助?請提供意見:

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

這個網頁
需要協助嗎?請前往我們的支援網頁