DECRYPT

DECRYPT (복호화)

VARCHAR 암호(passphrase)를 사용해 BINARY 값을 복호화해요.

참조: ENCRYPT, ENCRYPT_RAW, DECRYPT_RAW, TRY_DECRYPT, TRY_DECRYPT_RAW

출처: Snowflake SQL Reference - DECRYPT

본문

구문

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

인자

필수:

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와 암호의 차이는, 암호는 비밀로 유지되어야 하는 반면(그렇지 않으면 암호화는 본질적으로 무의미함) AAD는 공개될 수 있다는 점이에요. AAD는 공개 정보와 암호화된 값이 서로 연관되어 있음을 인증하는 데 도움을 줘요. ENCRYPT 함수의 예시 섹션에는 AAD가 일치할 때와 일치하지 않을 때의 동작을 보여주는 예시가 있어요.

ENCRYPT_RAW와 DECRYPT_RAW의 경우 AAD의 데이터 타입은 BINARY여야 해요. ENCRYPT와 DECRYPT의 경우 AAD의 데이터 타입은 VARCHAR 또는 BINARY일 수 있으며, 암호화된 값의 데이터 타입과 일치할 필요는 없어요.

AAD는 GCM(기본값) 같은 AEAD 지원 암호화 모드에서만 지원돼요.

encryption_method

데이터를 암호화/복호화하는 데 사용할 방법을 지정하는 문자열이에요. 이 문자열은 하위 필드를 포함해요:

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

알고리즘은 현재 다음으로 제한돼요:

  • 'AES': 암호가 전달되면(예: ENCRYPT에) 함수는 AES-256 암호화(256비트)를 사용해요. 키가 전달되면(예: ENCRYPT_RAW에) 함수는 키 길이에 따라 128, 192 또는 256비트 암호화를 사용해요.

알고리즘은 대소문자를 구분하지 않아요.

모드는 메시지를 암호화하는 데 사용할 블록 암호 모드를 지정해요. 다음 표는 지원되는 모드와 그중 어떤 모드가 패딩을 지원하는지 보여줘요:

모드 패딩 지원 설명
'ECB' Yes 키로 각 블록을 개별적으로 암호화해요. 이 모드는 일반적으로 권장되지 않으며 외부 구현과의 호환성을 위해 포함돼요.
'CBC' Yes 암호화된 블록이 이전 블록과 XOR됩니다.
'GCM' No Galois/Counter Mode는 AEAD 지원 고성능 암호화 모드예요. AEAD는 AEAD 태그를 생성해 암호화된 데이터의 진위성과 기밀성을 추가로 보장해요. 또한 AEAD는 AAD(추가 인증 데이터)를 지원해요.
'CTR' No 카운터 모드.
'OFB' No 출력 피드백. 암호문이 블록의 평문과 XOR됩니다.
'CFB' No 암호 피드백은 OFB와 CBC의 조합이에요.

모드는 대소문자를 구분하지 않아요.

패딩은 길이가 블록 크기의 배수가 아닌 메시지를 패딩하는 방법을 지정해요. 패딩은 ECB와 CBC 모드에만 적용되며, 다른 모드에서는 무시돼요. 패딩의 가능한 값:

  • 'PKCS': 블록 패딩에 PKCS5를 사용해요.
  • 'NONE': 패딩 없음. ECB 또는 CBC 모드를 사용할 때 사용자가 패딩을 처리해야 해요.

패딩은 대소문자를 구분하지 않아요.

기본 설정: 'AES-GCM'.

모드가 지정되지 않으면 GCM이 사용돼요.

패딩이 지정되지 않으면 PKCS가 사용돼요.

반환 값

복호화된 값을 BINARY 값으로 반환해요. 원래 값이 암호화 전 VARCHAR였다면 반환된 BINARY를 명시적으로 VARCHAR로 변환해야 해요. 예를 들어:

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

더 완전한 예시는 아래 Examples를 참고해요.

사용상 주의사항

  • ENCRYPT()로 암호화된 데이터를 복호화하려면 DECRYPT()를 사용해요. DECRYPT_RAW()를 사용하지 마세요.
  • ENCRYPT_RAW()로 암호화된 데이터를 복호화하려면 DECRYPT_RAW()를 사용해요. DECRYPT()를 사용하지 마세요.
  • 함수의 파라미터는 보안을 위해 마스킹돼요. 다음 같은 민감 정보는 쿼리 로그에 보이지 않고 Snowflake에도 보이지 않아요: 암호화 또는 복호화할 문자열 또는 이진 값, 암호 또는 키.
  • 함수는 FIPS 호환 암호화 라이브러리를 사용해 암호화와 복호화를 효과적으로 수행해요.
  • 데이터 조각을 복호화하는 데 사용되는 암호 또는 키는 그 데이터를 암호화하는 데 사용된 암호 또는 키와 같아야 해요.
  • 암호는 임의의 길이일 수 있으며, 심지어 0(빈 문자열)도 되지만 Snowflake는 적어도 8바이트인 암호를 사용할 것을 강력히 권장해요.
  • Snowflake는 암호가 대문자, 소문자, 숫자, 구두점을 섞어 쓰는 등 일반적인 비밀번호 모범 사례를 따르길 권장해요.
  • 암호는 입력을 암호화/복호화하는 데 직접 사용되지 않아요. 대신 암호는 암호화/복호화 키를 파생하는 데 사용되며, 같은 암호에 대해 항상 같아요. Snowflake는 PBKDF2 키 파생 함수를 Snowflake 내부 시드와 함께 사용해 주어진 암호에서 암호화/복호화 키를 계산해요. 이 키 파생 때문에 암호화/복호화 함수는 다음에 사용할 수 없어요: 외부에서 암호화된 데이터를 복호화하는 것, 외부에서 복호화될 데이터를 암호화하는 것. 이 중 하나를 하려면 ENCRYPT_RAW 또는 DECRYPT_RAW를 사용해요.

예시

아래 코드는 암호화와 복호화의 간단한 예시를 보여줘요:

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

이 예시는 간단한 암호로 BINARY 값을 복호화해요. 이 예시에서 이진 값은 16진수 형식으로 표시돼요. 암호화된 데이터의 값은 초기화 벡터의 무작위성(ENCRYPT에서 간략히 설명)으로 인해 다를 수 있어요.

ALTER SESSION SET BINARY_OUTPUT_FORMAT='hex';
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');
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                 |
+----------------+---------------+---------+------------+-----------------------+

이 예시는 암호화 방법 지정자의 일부로 대체 모드(CBC)를 사용하는 방법을 보여줘요. 이 암호화 방법은 패딩 규칙(PKCS)도 지정해요. 이 예시에서 AAD 파라미터는 NULL이에요.

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

이 예시는 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 |
+------------+

잘못된 AAD를 전달하면 복호화가 실패해요:

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

더 알아보기