类别:

加密函数

DECRYPT

使用 VARCHAR 加密短语对 BINARY 值进行解密。

另请参阅:

ENCRYPTENCRYPT_RAWDECRYPT_RAWTRY_DECRYPTTRY_DECRYPT_RAW

语法

DECRYPT( <value_to_decrypt> , <passphrase> ,
         [ [ <additional_authenticated_data> , ] <encryption_method> ]
       )
Copy

实参

必填:

value_to_decrypt

要解密的 BINARY 值。

passphrase

用于加密/解密数据的加密短语。加密短语是 VARCHAR。

可选:

additional_authenticated_data

经过身份验证的额外数据 (AAD) 是在解密过程中机密性和真实性都有保证的附加数据。然而,此 AAD 未加密,并且不作为字段包含在 ENCRYPT 或者 ENCRYPT_RAW 函数的返回值中。

如果 AAD 被传递给加密函数(ENCRYPT 或 ENCRYPT_RAW),那么相同的 AAD 也必须传递给解密函数(DECRYPT 或者 DECRYPT_RAW)。如果传递给解密函数的 AAD 与 AAD 不匹配,则解密失败。

AAD 和 passphrase 之间的区别是密码短语旨在保密(否则,加密实际上毫无价值),而 AAD 可以保持公开。AAD 有助于验证公共信息和加密值是否相互关联。ENCRYPT 函数中的示例部分包括一个示例,展示了 AAD 匹配与不匹配时的行为。

对于 ENCRYPT_RAW 和 DECRYPT_RAW,AAD 的数据类型应为 BINARY。对于 ENCRYPT 和 DECRYPT,AAD 的数据类型可以是 VARCHAR 或者 BINARY,并且不需要匹配加密值的数据类型。

AAD 仅支持启用 AEAD 的加密模式,例如 GCM(默认)。

encryption_method

该字符串指定用于加密/解密数据的方法。该字符串包含子字段:

<algorithm>-<mode> [ /pad: <padding> ]
Copy

algorithm 目前仅限于:

  • 'AES':传递加密短语时(例如,传递至 ENCRYPT),该函数会使用 AES-256 加密(256 位)。传递密钥时(例如,传递至 ENCRYPT_RAW),该函数使用 128、192 或 256 位加密,具体取决于密钥长度。

algorithm 不区分大小写。

mode 指定应使用哪种分组密码模式来加密消息。下表显示了哪些模式受支持,以及其中哪些模式支持填充:

模式

填充

描述

'ECB'

使用密钥单独加密每个分组。通常不鼓励使用此模式,包含此模式只是为了与外部实现兼容。

'CBC'

加密后的分组是与前一个分组 XORed。

'GCM'

Galois/Counter 模式是一种启用了 AEAD 的高性能加密模式。AEAD 通过生成一个额外的 AEAD 标签来确保加密数据的真实性和机密性。而且,AEAD 支持 AAD(经过身份验证的额外数据)。

'CTR'

计数器模式。

'OFB'

输出反馈。密文是附带块纯文本的 XORed。

'CFB'

密码反馈由 OFB 和 CBC 组成。

mode 不区分大小写。

padding 指定如何填充长度不是块大小倍数的消息。填充仅适用于 ECB 和 CBC 模式;对于其他模式,填充将被忽略。填充的可能值为:

  • 'PKCS':将 PKCS5 用于块填充。

  • 'NONE':无填充。用户在使用 ECB 或者 CBC 模式时需要注意填充。

padding 不区分大小写。

默认设置:'AES-GCM'

如果未指定 mode,则会使用 GCM。

如果未指定 padding,则会使用 PKCS。

返回

以 BINARY 值形式返回解密的值。如果加密前的原始值为 VARCHAR,则必须将返回的 BINARY 显式转换回 VARCHAR。例如:

... TO_VARCHAR(DECRYPT(ENCRYPT('secret', 'key'), 'key'), 'utf-8') ...
Copy

有关更完整的示例,请参阅以下 示例

使用说明

  • 要解密通过 ENCRYPT() 加密的数据,请使用 DECRYPT()。请勿使用 DECRYPT_RAW()

  • 要解密通过 ENCRYPT_RAW() 加密的数据,请使用 DECRYPT_RAW()。请勿使用 DECRYPT()

  • 为了安全起见,已掩码该函数的参数。以下所示的敏感信息在查询日志中不可见,并且对 Snowflake 不可见:

    • 要加密或解密的字符串或二进制值。

    • 加密短语或密钥。

  • 这些函数使用兼容 FIPS 的密码库,有效地执行加密和解密。

  • 用于解密数据的加密短语或密钥必须与用于加密该数据的加密短语或密钥相同。

  • 加密短语可以是任意长度,甚至可以是 0(空字符串)。但是,Snowflake 强烈建议使用至少包含 8 个字节的加密短语。

  • Snowflake 建议加密短语遵循密码的通用最佳实践,例如混合使用大写字母、小写字母、数字和标点符号。

  • 加密短语不直接用于加密/解密输入。相反,加密短语用于派生加密/解密密钥,该密钥对于同一加密短语始终相同。Snowflake 使用带有 Snowflake 内部种子的 https://en.wikipedia.org/wiki/PBKDF2 (link removed) 密钥派生函数,通过给定的加密短语计算加密/解密密钥。

    因为存在此密钥派生,加密/解密函数不能用于:

    • 解密外部加密的数据。

    • 加密将进行外部解密的数据。

    若要执行其中任一操作,请使用 ENCRYPT_RAWDECRYPT_RAW

示例

下面的代码显示了加密和解密的简单示例:

SET passphrase='poiuqewjlkfsd';
Copy
SELECT
    TO_VARCHAR(
        DECRYPT(
            ENCRYPT('Patient tested positive for COVID-19', $passphrase),
            $passphrase),
        'utf-8')
        AS dcrypt
    ;
+--------------------------------------+
| DCRYPT                               |
|--------------------------------------|
| Patient tested positive for COVID-19 |
+--------------------------------------+
Copy

此示例使用简单加密短语对 BINARY 值进行解密。在此示例中,二进制值以 十六进制 格式显示。加密数据的值可能会因初始化向量的随机性而变化(在 :doc:`encrypt`中有简要描述)。

ALTER SESSION SET BINARY_OUTPUT_FORMAT='hex';
Copy
CREATE TABLE binary_table (
    binary_column BINARY,
    encrypted_binary_column BINARY);
INSERT INTO binary_table (binary_column) 
    SELECT (TO_BINARY(HEX_ENCODE('Hello')));
UPDATE binary_table 
    SET encrypted_binary_column = ENCRYPT(binary_column, 'SamplePassphrase');
Copy
SELECT 'Hello' as original_value,
       binary_column, 
       hex_decode_string(to_varchar(binary_column)) as decoded,
       -- encrypted_binary_column,
       decrypt(encrypted_binary_column, 'SamplePassphrase') as decrypted,
       hex_decode_string(to_varchar(decrypt(encrypted_binary_column, 'SamplePassphrase'))) as decrypted_and_decoded
    FROM binary_table;
+----------------+---------------+---------+------------+-----------------------+
| ORIGINAL_VALUE | BINARY_COLUMN | DECODED | DECRYPTED  | DECRYPTED_AND_DECODED |
|----------------+---------------+---------+------------+-----------------------|
| Hello          | 48656C6C6F    | Hello   | 48656C6C6F | Hello                 |
+----------------+---------------+---------+------------+-----------------------+
Copy

此示例展示如何将备用模式 (CBC) 用作加密方法说明符的一部分。此加密方法还会指定填充规则 (PKCS)。在此示例中,AAD 参数为 NULL。

select encrypt(to_binary(hex_encode('secret!')), 'sample_passphrase', NULL, 'aes-cbc/pad:pkcs') as encrypted_data;
Copy

此示例展示如何使用 AAD:

SELECT
    TO_VARCHAR(
        DECRYPT(
            ENCRYPT('penicillin', $passphrase, 'John Dough AAD', 'aes-gcm'),
            $passphrase, 'John Dough AAD', 'aes-gcm'),
        'utf-8')
        AS medicine
    ;
+------------+
| MEDICINE   |
|------------|
| penicillin |
+------------+
Copy

如果传递错误的 AAD,解密将失败:

SELECT
    DECRYPT(
        ENCRYPT('penicillin', $passphrase, 'John Dough AAD', 'aes-gcm'),
        $passphrase, 'wrong patient AAD', 'aes-gcm') AS medicine
    ;
Copy
100311 (22023): Decryption failed. Check encrypted data, key, AAD, or AEAD tag.
Copy
语言: 中文