ENCRYPT

ENCRYPT

ENCRYPT()는 VARCHAR 패스프레이즈를 사용해 VARCHAR 또는 BINARY 값을 암호화해요.

함께 보기:

ENCRYPT_RAW , DECRYPT , DECRYPT_RAW , TRY_DECRYPT , TRY_DECRYPT_RAW

출처: Snowflake SQL Reference

본문

문법

ENCRYPT( <value_to_encrypt> , <passphrase> ,
         [ [ <additional_authenticated_data> , ] <encryption_method> ]
       )

인자

필수:

value_to_encrypt

암호화할 VARCHAR 또는 BINARY 값이에요.

passphrase

데이터를 암호화/복호화하는 데 사용할 패스프레이즈예요. 패스프레이즈는 value_to_encrypt가 VARCHAR이든 BINARY이든 항상 VARCHAR예요.

선택:

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

additional_authenticated_data

부가 인증 데이터(Additional Authenticated Data, AAD)는 복호화 과정에서 기밀성과 무결성이 보장되는 추가 데이터예요. 그러나 이 AAD는 암호화되지 않으며 ENCRYPT 또는 ENCRYPT_RAW 함수가 반환하는 값에 필드로 포함되지 않아요. AAD가 암호화 함수(ENCRYPT 또는 ENCRYPT_RAW)에 전달되면, 복호화 함수(DECRYPT 또는 DECRYPT_RAW)에도 같은 AAD를 전달해야 해요. 복호화 함수에 전달된 AAD가 암호화 함수에 전달된 AAD와 일치하지 않으면 복호화는 실패해요. AAD와 패스프레이즈의 차이는, 패스프레이즈는 비밀로 유지해야 하지만(그렇지 않으면 암호화가 사실상 무용지물) AAD는 공개된 채로 남길 수 있다는 점이에요. AAD는 공개 정보와 암호화된 값이 서로 연관되어 있음을 인증하는 데 도움을 줘요. ENCRYPT 함수의 예제 섹션에는 AAD가 일치할 때와 일치하지 않을 때의 동작을 보여주는 예제가 있어요. ENCRYPT_RAW와 DECRYPT_RAW의 경우 AAD의 데이터 타입은 BINARY여야 해요. ENCRYPT와 DECRYPT의 경우 AAD의 데이터 타입은 VARCHAR 또는 BINARY일 수 있고, 암호화된 값의 데이터 타입과 일치할 필요는 없어요. AAD는 GCM(기본값) 같은 AEAD 지원 암호화 모드에서만 지원돼요.

encryption_method

이 문자열은 데이터를 암호화/복호화하는 데 사용할 방식을 지정해요. 이 문자열은 하위 필드를 포함해요. 알고리즘은 현재 다음으로 제한돼요: 'AES': 패스프레이즈가 전달되면(예: ENCRYPT에) 함수는 AES-256 암호화(256비트)를 사용해요. 키가 전달되면(예: ENCRYPT_RAW에) 함수는 키 길이에 따라 128, 192, 256비트 암호화를 사용해요. 알고리즘은 대소문자를 구분하지 않아요. 모드는 메시지를 암호화하는 데 사용할 블록 암호 모드를 지정해요. 다음 표는 지원되는 모드와 그 모드 중 어떤 것이 패딩을 지원하는지 보여줘요.

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

모드는 대소문자를 구분하지 않아요. 패딩은 블록 크기의 배수가 아닌 길이의 메시지를 어떻게 패딩할지 지정해요. 패딩은 ECB와 CBC 모드에만 적용되며, 다른 모드에서는 무시돼요. 패딩의 가능한 값은: 'PKCS': 블록 패딩에 PKCS5를 사용. 'NONE': 패딩 없음. ECB 또는 CBC 모드를 사용할 때는 사용자가 패딩을 직접 처리해야 해요. 패딩은 대소문자를 구분하지 않아요. 기본 설정: 'AES-GCM'. 모드를 지정하지 않으면 GCM이 사용돼요. 패딩을 지정하지 않으면 PKCS가 사용돼요.

반환

반환되는 값의 데이터 타입은 BINARY예요.

단일 값만 반환되지만, 그 값에는 두 개 또는 세 개의 연결된 필드가 포함돼요.

  • 첫 번째 필드는 초기화 벡터(IV)예요. IV는 CTR-DRBG 난수 생성기를 사용해 무작위로 생성돼요. 암호화와 복호화 모두 IV를 사용해요.

  • 두 번째 필드는 *value_to_encrypt*의 암호문(암호화된 값)이에요.

  • 암호화 모드가 AEAD 지원이면 반환 값에 AEAD 태그인 세 번째 필드도 포함돼요.

IV와 태그 크기는 암호화 모드에 따라 달라져요.

사용 지침

  • ENCRYPT()로 암호화한 데이터를 복호화하려면 DECRYPT()를 사용해요. DECRYPT_RAW()는 사용하지 마세요.

  • ENCRYPT_RAW()로 암호화한 데이터를 복호화하려면 DECRYPT_RAW()를 사용해요. DECRYPT()는 사용하지 마세요.

  • 함수의 매개변수는 보안을 위해 마스킹돼요. 다음 같은 민감한 정보는 쿼리 로그에서 볼 수 없고 Snowflake에도 노출되지 않아요.

    • 암호화하거나 복호화할 문자열 또는 이진 값.

    • 패스프레이즈 또는 키.

  • 함수는 암호화와 복호화를 효과적으로 수행하기 위해 FIPS 호환 암호화 라이브러리를 사용해요.

  • 데이터를 복호화하는 데 사용하는 패스프레이즈 또는 키는 그 데이터를 암호화하는 데 사용한 패스프레이즈 또는 키와 동일해야 해요.

  • 패스프레이즈는 길이에 제한이 없으며 0(빈 문자열)도 가능해요. 그러나 Snowflake는 최소 8바이트 이상의 패스프레이즈를 사용할 것을 강력히 권장해요.

  • Snowflake는 패스프레이즈가 대문자, 소문자, 숫자, 구두점을 섞어 쓰는 등 일반적인 비밀번호 모범 사례를 따르기를 권장해요.

  • 패스프레이즈는 입력을 암호화/복호화하는 데 직접 사용되지 않아요. 대신 패스프레이즈는 암호화/복호화 키를 파생하는 데 사용되며, 같은 패스프레이즈에 대해 항상 같은 키를 생성해요. Snowflake는 Snowflake 내부 시드를 사용하는 PBKDF2 키 파생 함수를 사용해 주어진 패스프레이즈로 암호화/복호화 키를 계산해요.

이 키 파생 때문에 암호화/복호화 함수는 다음 용도로는 사용할 수 없어요.

  • 외부에서 암호화된 데이터를 복호화.

  • 외부에서 복호화할 데이터를 암호화.

이 둘 중 하나를 하려면 ENCRYPT_RAW 또는 DECRYPT_RAW를 사용하세요.

  • 초기화 벡터는 항상 무작위로 재생성되므로, 같은 *value_to_encrypt*와 *passphrase*로 ENCRYPT()를 호출해도 매번 같은 결과가 반환되지 않아요. 같은 *value_to_encrypt*와 *passphrase*에 대해 같은 출력을 생성해야 한다면 ENCRYPT_RAW를 사용하고 초기화 벡터를 지정하는 것을 고려하세요.

예제

이 예제는 간단한 패스프레이즈로 VARCHAR를 암호화해요.

SELECT encrypt('Secret!', 'SamplePassphrase');

출력은 사람이 쉽게 읽을 수 없는 텍스트예요.

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

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 |
+--------------------------------------+

이 예제는 *value_to_encrypt*와 인증 데이터에 BINARY 값을 사용해요.

SELECT encrypt(to_binary(hex_encode('Secret!')), 'SamplePassphrase', to_binary(hex_encode('Authenticated Data')));

출력은:

6E1361E297C22969345F978A45205E3E98EB872844E3A0F151713894C273FAEF50C365S

이 예제는 암호화 방식 지정자의 일부로 대체 모드(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.

더 알아보기