Categorias:

Funções de criptografia

DECRYPT_RAW

Descriptografa um valor BINARY usando uma chave BINARY.

Consulte também:

ENCRYPT , ENCRYPT_RAW , DECRYPT , TRY_DECRYPT , TRY_DECRYPT_RAW

Sintaxe

DECRYPT_RAW( <value_to_decrypt> , <key> , <iv> ,
         [ [ [ <additional_authenticated_data> , ] <encryption_method> , ] <aead_tag> ]
       )
Copy

Argumentos

Obrigatório:

value_to_decrypt

O valor binário a ser descriptografado.

key

A chave a ser usada para criptografar/descriptografar os dados. A chave deve ser um valor BINARY. A chave pode ser de qualquer valor desde que o comprimento esteja correto. Por exemplo, para AES128, a chave deve ser 128 bits (16 bytes), e para AES256, a chave deve ser 256 bits (32 bytes).

A chave usada para criptografar o valor deve ser usada para descriptografar o valor.

iv

Este parâmetro contém o vetor de inicialização (IV) a ser usado para criptografar e descriptografar esta parte do dado. O IV deve ser um valor BINARY de um comprimento específico:

  • Para GCM, este campo deve ser 96 bits (12 bytes). Enquanto o método de criptografia GCM permite que este campo tenha um tamanho diferente, o Snowflake atualmente oferece suporte apenas a 96 bits.

  • Para CCM, isto deve ser 56 bits (7 bytes).

  • Para ECB, este parâmetro é desnecessário.

  • Para todos os outros modos de criptografia suportados, isto deve ser 128 bits (16 bytes).

Este valor é usado para inicializar a primeira rodada de criptografia. Nunca se deve usar a mesma combinação de IV e chaves mais de uma vez, especialmente para modos de criptografia como GCM.

Se este parâmetro for definido como NULL, a implementação escolherá um novo IV pseudoaleatório durante cada chamada.

Opcional:

additional_authenticated_data

Dados autenticados adicionais (AAD) são dados adicionais cuja confidencialidade e autenticidade são asseguradas durante o processo de descriptografia. Entretanto, este AAD não é criptografado e não está incluído como campo no valor retornado da função ENCRYPT ou ENCRYPT_RAW.

Se AAD for passado para a função de criptografia (ENCRYPT ou ENCRYPT_RAW), então o mesmo AAD deve ser passado para a função de descriptografia (DECRYPT ou DECRYPT_RAW). Se AAD passado para a função de descriptografia não corresponder ao AAD passado para a função de criptografia, então a descriptografia falha.

A diferença entre o AAD e o passphrase é que a frase secreta deve ser mantida em segredo (caso contrário, a criptografia é essencialmente inútil), enquanto o AAD pode ser deixado público. O AAD ajuda a autenticar que uma informação pública e um valor criptografado estão associados uns aos outros. A seção de exemplos na função ENCRYPT inclui um exemplo mostrando o comportamento quando o AAD é correspondente e o comportamento quando não é correspondente.

Para ENCRYPT_RAW e DECRYPT_RAW, o tipo de dados do AAD deve ser BINARY. Para ENCRYPT e DECRYPT, o tipo de dados do AAD pode ser VARCHAR ou BINARY, e não precisa corresponder ao tipo de dados do valor que foi criptografado.

AAD é suportado somente por modos de criptografia habilitados para AEAD, como GCM (padrão).

encryption_method

Esta cadeia de caracteres especifica o método a ser usado para criptografar/descriptografar os dados. Esta cadeia de caracteres contém subcampos:

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

O algorithm está atualmente limitado a:

  • 'AES': quando uma senha é passada (por exemplo, para ENCRYPT), a função usa criptografia AES-256 (256 bits). Quando uma chave é passada (por exemplo, para ENCRYPT_RAW), a função usa criptografia de 128, 192 ou 256 bits, dependendo do comprimento da chave.

O algorithm não diferencia maiúsculas e minúsculas.

O mode especifica que modo de codificação de bloco deve ser usado para criptografar mensagens. A tabela a seguir mostra quais modos são suportados, e quais desses modos suportam o preenchimento:

Modo

Preenchimento

Descrição

'ECB'

Sim

Criptografar cada bloco individualmente com a chave. Este modo é geralmente desencorajado e está incluído apenas para compatibilidade com implementações externas.

'CBC'

Sim

O bloco criptografado é XORed com o bloco anterior.

'GCM'

Não

O Modo Galois/Contador é um modo de criptografia de alto desempenho habilitado para AEAD. AEAD também garante a autenticidade e a confidencialidade dos dados criptografados, gerando uma tag AEAD. Além disso, AEAD oferece suporte a AAD (dados autenticados adicionais).

'CTR'

Não

Modo contador.

'OFB'

Não

Feedback de saída. O texto cifrado é XORed com o texto sem formatação de um bloco.

'CFB'

Não

O feedback da cifra é uma combinação de OFB e CBC.

O mode não diferencia maiúsculas e minúsculas.

O padding especifica como preencher mensagens cujo comprimento não seja múltiplo do tamanho do bloco. O preenchimento é aplicável somente para os modos ECB e CBC; o preenchimento é ignorado para outros modos. Os valores possíveis para o preenchimento são:

  • 'PKCS': utiliza PKCS5 para preenchimento de blocos.

  • 'NONE': sem preenchimento. O usuário precisa cuidar do preenchimento ao usar o modo ECB ou CBC.

O padding não diferencia maiúsculas e minúsculas.

Configuração padrão: 'AES-GCM'.

Se o mode não for especificado, é utilizado GCM.

Se o padding não for especificado, é utilizado PKCS.

aead_tag

Este valor BINARY é necessário para modos de descriptografia habilitados para AEAD para verificar a autenticidade e a confidencialidade dos dados criptografados. Use a tag AEAD retornada pela função ENCRYPT_RAW. Um exemplo abaixo mostra como acessar e utilizar este valor.

Retornos

A função retorna o valor descriptografado. O tipo de dados do valor retornado é BINARY.

Notas de uso

  • Para descriptografar dados criptografados por ENCRYPT(), use DECRYPT(). Não usar DECRYPT_RAW().

  • Para descriptografar dados criptografados por ENCRYPT_RAW(), use DECRYPT_RAW(). Não usar DECRYPT().

  • Os parâmetros da função são mascarados para segurança. Informações sensíveis como as seguintes não são visíveis no log de consulta e não são visíveis para o Snowflake:

    • O valor da cadeia de caracteres ou binário para criptografar ou descriptografar.

    • A frase secreta ou senha.

  • As funções utilizam uma biblioteca criptográfica compatível com FIPS para realizar a criptografia e descriptografia de forma eficaz.

  • A senha ou chave usada para decodificar um dado deve ser a mesma que a senha ou chave usada para codificar esses dados.

  • Ao extrair campos (texto cifrado, vetor de inicialização ou tag) de um valor binário criptografado, usar:

    as_binary(get(encrypted_value, '<field_name>'))
    
    Copy

    Por exemplo, usar:

    as_binary(get(encrypted_value, 'ciphertext'))
    
    Copy

    Não usar encrypted_value:field_name::binary. O operador de acesso ao campo : converte o valor do campo extraído em uma cadeia de caracteres; entretanto, como a fonte é BINARY, essa cadeia de caracteres nem sempre é uma cadeia de caracteres de UTF-8 válida.

Exemplos

Este exemplo mostra criptografia e descriptografia.

Para facilitar a leitura, defina BINARY_OUTPUT_FORMAT como HEX:

ALTER SESSION SET BINARY_OUTPUT_FORMAT='HEX';
Copy

Crie uma tabela e carregue-a.

Cuidado

Para simplificar este exemplo, a chave de criptografia/descriptografia é armazenada na tabela com o valor que foi criptografado. Isso não é seguro; a chave nunca deve ser armazenada como um valor não criptografado na tabela que armazena os dados criptografados.

CREATE OR REPLACE TABLE binary_table (
    encryption_key BINARY,   -- DO NOT STORE REAL ENCRYPTION KEYS THIS WAY!
    initialization_vector BINARY(12), -- DO NOT STORE REAL IV'S THIS WAY!!
    binary_column BINARY,
    encrypted_binary_column VARIANT,
    aad_column BINARY);

INSERT INTO binary_table (encryption_key,
                          initialization_vector,
                          binary_column,
                          aad_column)
    SELECT SHA2_BINARY('NotSecretEnough', 256),
            SUBSTR(TO_BINARY(HEX_ENCODE('AlsoNotSecretEnough'), 'HEX'), 0, 12),
            TO_BINARY(HEX_ENCODE('Bonjour'), 'HEX'),
            TO_BINARY(HEX_ENCODE('additional data'), 'HEX')
    ;
Copy

Criptografar:

UPDATE binary_table SET encrypted_binary_column =
    ENCRYPT_RAW(binary_column, 
        encryption_key, 
        initialization_vector, 
        aad_column,
        'AES-GCM');
+------------------------+-------------------------------------+
| number of rows updated | number of multi-joined rows updated |
|------------------------+-------------------------------------|
|                      1 |                                   0 |
+------------------------+-------------------------------------+
Copy

Isto mostra a chamada correspondente para a função DECRYPT_RAW(). O vetor de inicialização (IV) é obtido do valor criptografado; não é necessário armazenar o vetor de inicialização separadamente. Da mesma forma, a tag AEAD também é lida a partir do valor criptografado.

Cuidado

Para simplificar este exemplo, a chave de criptografia/descriptografia é lida a partir da tabela com o valor que foi criptografado. Isso não é seguro; a chave nunca deve ser armazenada como um valor não criptografado na tabela que armazena os dados criptografados.

SELECT 'Bonjour' as original_value,
       binary_column,
       hex_decode_string(to_varchar(binary_column)) as decoded,
       encrypted_binary_column,
       decrypt_raw(as_binary(get(encrypted_binary_column, 'ciphertext')),
                  encryption_key,
                  as_binary(get(encrypted_binary_column, 'iv')),
                  aad_column,
                  'AES-GCM',
                  as_binary(get(encrypted_binary_column, 'tag')))
           as decrypted,
       hex_decode_string(to_varchar(decrypt_raw(as_binary(get(encrypted_binary_column, 'ciphertext')),
                  encryption_key,
                  as_binary(get(encrypted_binary_column, 'iv')),
                  aad_column,
                  'AES-GCM',
                  as_binary(get(encrypted_binary_column, 'tag')))
                  ))
           as decrypted_and_decoded
    FROM binary_table;
+----------------+----------------+---------+---------------------------------------------+----------------+-----------------------+
| ORIGINAL_VALUE | BINARY_COLUMN  | DECODED | ENCRYPTED_BINARY_COLUMN                     | DECRYPTED      | DECRYPTED_AND_DECODED |
|----------------+----------------+---------+---------------------------------------------+----------------+-----------------------|
| Bonjour        | 426F6E6A6F7572 | Bonjour | {                                           | 426F6E6A6F7572 | Bonjour               |
|                |                |         |   "ciphertext": "CA2F4A383F6F55",           |                |                       |
|                |                |         |   "iv": "416C736F4E6F745365637265",         |                |                       |
|                |                |         |   "tag": "91F28FBC6A2FE9B213D1C44B8D75D147" |                |                       |
|                |                |         | }                                           |                |                       |
+----------------+----------------+---------+---------------------------------------------+----------------+-----------------------+
Copy

O exemplo anterior duplicou uma longa chamada para DECRYPT_RAW(). Você pode usar uma cláusula WITH para reduzir a duplicação:

WITH
    decrypted_but_not_decoded as (
        decrypt_raw(as_binary(get(encrypted_binary_column, 'ciphertext')),
                      encryption_key,
                      as_binary(get(encrypted_binary_column, 'iv')),
                      aad_column,
                      'AES-GCM',
                      as_binary(get(encrypted_binary_column, 'tag')))
    )
SELECT 'Bonjour' as original_value,
       binary_column,
       hex_decode_string(to_varchar(binary_column)) as decoded,
       encrypted_binary_column,
       decrypted_but_not_decoded,
       hex_decode_string(to_varchar(decrypted_but_not_decoded))
           as decrypted_and_decoded
    FROM binary_table;
+----------------+----------------+---------+---------------------------------------------+---------------------------+-----------------------+
| ORIGINAL_VALUE | BINARY_COLUMN  | DECODED | ENCRYPTED_BINARY_COLUMN                     | DECRYPTED_BUT_NOT_DECODED | DECRYPTED_AND_DECODED |
|----------------+----------------+---------+---------------------------------------------+---------------------------+-----------------------|
| Bonjour        | 426F6E6A6F7572 | Bonjour | {                                           | 426F6E6A6F7572            | Bonjour               |
|                |                |         |   "ciphertext": "CA2F4A383F6F55",           |                           |                       |
|                |                |         |   "iv": "416C736F4E6F745365637265",         |                           |                       |
|                |                |         |   "tag": "91F28FBC6A2FE9B213D1C44B8D75D147" |                           |                       |
|                |                |         | }                                           |                           |                       |
+----------------+----------------+---------+---------------------------------------------+---------------------------+-----------------------+
Copy