본문으로 바로가기
본문으로 바로가기

암호화 함수

이 함수들은 AES (Advanced Encryption Standard) 알고리즘을 사용하여 데이터를 암호화하고 복호화합니다.

키 길이는 암호화 모드에 따라 달라지며, -128-, -196-, -256- 모드에서는 각각 16, 24, 32 바이트 길이의 키를 사용합니다.

초기화 벡터의 길이는 항상 16바이트이며, 16바이트를 초과하는 부분은 무시됩니다.

HMAC

도입된 버전: v25.12

지정된 해시 알고리즘과 비밀 키를 사용하여 주어진 메시지에 대한 HMAC(Hash-based Message Authentication Code)를 계산합니다.

지원되는 해시 알고리즘:

  • RSA-MD4 (별칭: MD4, RSA-MD4)
  • RSA-MD5 (별칭: MD5, RSA-MD5)
  • RSA-MDC2 (별칭: MDC2, RSA-MDC2)
  • RSA-RIPEMD160 (별칭: RIPEMD160, RSA-RIPEMD160)
  • RSA-SHA1 (별칭: RSA-SHA1, SHA1)
  • RSA-SHA1-2 (별칭: RSA-SHA1, RSA-SHA1-2)
  • RSA-SHA224 (별칭: RSA-SHA224, SHA224)
  • RSA-SHA256 (별칭: RSA-SHA256, SHA256)
  • RSA-SHA3-224 (별칭: RSA-SHA3-224, SHA3-224)
  • RSA-SHA3-256 (별칭: RSA-SHA3-256, SHA3-256)
  • RSA-SHA3-384 (별칭: RSA-SHA3-384, SHA3-384)
  • RSA-SHA3-512 (별칭: RSA-SHA3-512, SHA3-512)
  • RSA-SHA384 (별칭: RSA-SHA384, SHA384)
  • RSA-SHA512 (별칭: RSA-SHA512, SHA512)
  • RSA-SHA512/224 (별칭: RSA-SHA512/224, SHA512-224)
  • RSA-SHA512/256 (별칭: RSA-SHA512/256, SHA512-256)
  • RSA-SM3 (별칭: RSA-SM3, SM3)
  • blake2b512
  • blake2s256
  • id-rsassa-pkcs1-v1_5-with-sha3-224 (별칭: SHA3-224, id-rsassa-pkcs1-v1_5-with-sha3-224)
  • id-rsassa-pkcs1-v1_5-with-sha3-256 (별칭: SHA3-256, id-rsassa-pkcs1-v1_5-with-sha3-256)
  • id-rsassa-pkcs1-v1_5-with-sha3-384 (별칭: SHA3-384, id-rsassa-pkcs1-v1_5-with-sha3-384)
  • id-rsassa-pkcs1-v1_5-with-sha3-512 (별칭: SHA3-512, id-rsassa-pkcs1-v1_5-with-sha3-512)
  • md4
  • md4WithRSAEncryption (별칭: MD4, md4WithRSAEncryption)
  • md5
  • md5-sha1
  • md5WithRSAEncryption (별칭: MD5, md5WithRSAEncryption)
  • mdc2
  • mdc2WithRSA (별칭: MDC2, mdc2WithRSA)
  • ripemd (별칭: RIPEMD160, ripemd)
  • ripemd160
  • ripemd160WithRSA (별칭: RIPEMD160, ripemd160WithRSA)
  • rmd160 (별칭: RIPEMD160, rmd160)
  • sha1
  • sha1WithRSAEncryption (별칭: SHA1, sha1WithRSAEncryption)
  • sha224
  • sha224WithRSAEncryption (별칭: SHA224, sha224WithRSAEncryption)
  • sha256
  • sha256WithRSAEncryption (별칭: SHA256, sha256WithRSAEncryption)
  • sha3-224
  • sha3-256
  • sha3-384
  • sha3-512
  • sha384
  • sha384WithRSAEncryption (별칭: SHA384, sha384WithRSAEncryption)
  • sha512
  • sha512-224
  • sha512-224WithRSAEncryption (별칭: SHA512-224, sha512-224WithRSAEncryption)
  • sha512-256
  • sha512-256WithRSAEncryption (별칭: SHA512-256, sha512-256WithRSAEncryption)
  • sha512WithRSAEncryption (별칭: SHA512, sha512WithRSAEncryption)
  • shake128
  • shake256
  • sm3
  • sm3WithRSAEncryption (별칭: SM3, sm3WithRSAEncryption)
  • ssl3-md5 (별칭: MD5, ssl3-md5)
  • ssl3-sha1 (별칭: SHA1, ssl3-sha1)
  • whirlpool

구문

HMAC(mode, message, key)

매개변수

  • mode — 해시 알고리즘 이름(대소문자 구분 없음). 지원되는 알고리즘: md5, sha1, sha224, sha256, sha384, sha512. String
  • message — 인증할 메시지. String
  • key — HMAC을 위한 비밀 키. String

반환 값

HMAC 다이제스트가 포함된 이진 문자열을 반환합니다. String

예시

기본 HMAC-SHA256

SELECT hex(HMAC('sha256', 'The quick brown fox jumps over the lazy dog', 'secret_key'));
┌─hex(HMAC('sha256', 'The quick brown fox jumps over the lazy dog', 'secret_key'))─┐
│ 31FD15FA0F61FD40DC09D919D4AA5B4141A0B27C1D51E74A6789A890AAAA187C                 │
└──────────────────────────────────────────────────────────────────────────────────┘

다양한 해시 알고리즘

SELECT
    hex(HMAC('md5', 'message', 'key')) AS hmac_md5,
    hex(HMAC('sha1', 'message', 'key')) AS hmac_sha1,
    hex(HMAC('sha256', 'message', 'key')) AS hmac_sha256;
┌─hmac_md5─────────────────────────┬─hmac_sha1────────────────────────────────┬─hmac_sha256──────────────────────────────────────────────────────┐
│ 4E4748E62B463521F6775FBF921234B5 │ 2088DF74D5F2146B48146CAF4965377E9D0BE3A4 │ 6E9EF29B75FFFC5B7ABAE527D58FDADB2FE42E7219011976917343065F58ED4A │
└──────────────────────────────────┴──────────────────────────────────────────┴──────────────────────────────────────────────────────────────────┘

대소문자 구분 없음 모드

SELECT
    hmac('SHA256', 'message', 'key') = HMAC('sha256', 'message', 'key') AS same_result,
    HMAC('SHA256', 'message', 'key') = Hmac('Sha256', 'message', 'key') AS also_same;
┌─same_result─┬─also_same─┐
│           1 │         1 │
└─────────────┴───────────┘

aes_decrypt_mysql

도입 버전: v20.12

MySQL의 AES_ENCRYPT 함수로 암호화된 데이터를 복호화합니다.

동일한 입력에 대해 decrypt와 동일한 평문을 생성합니다. key 또는 iv의 길이가 일반적으로 필요한 길이보다 더 긴 경우, aes_decrypt_mysql는 MySQL의 aes_decrypt 동작을 그대로 따라 key를 접어(fold) 사용하고 iv의 초과 비트는 무시합니다.

다음 복호화 모드를 지원합니다:

  • aes-128-ecb, aes-192-ecb, aes-256-ecb
  • aes-128-cbc, aes-192-cbc, aes-256-cbc
  • aes-128-cfb128
  • aes-128-ofb, aes-192-ofb, aes-256-ofb

구문

aes_decrypt_mysql(mode, ciphertext, key[, iv])

인수

  • mode — 복호화 모드. String
  • ciphertext — 복호화해야 하는 암호화된 텍스트. String
  • key — 복호화 키. String
  • iv — 선택 사항인 초기화 벡터(Initialization Vector). String

반환 값

복호화된 String을 반환합니다. String

예시

MySQL 데이터 복호화

-- Let's decrypt data we've previously encrypted with MySQL:
mysql> SET  block_encryption_mode='aes-256-ofb';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT aes_encrypt('Secret', '123456789101213141516171819202122', 'iviviviviviviviv123456') as ciphertext;
+------------------------+
| ciphertext             |
+------------------------+
| 0x24E9E4966469         |
+------------------------+
1 row in set (0.00 sec)

SELECT aes_decrypt_mysql('aes-256-ofb', unhex('24E9E4966469'), '123456789101213141516171819202122', 'iviviviviviviviv123456') AS plaintext
┌─plaintext─┐
│ Secret    │
└───────────┘

aes_encrypt_mysql

도입 버전: v20.12

MySQL의 AES_ENCRYPT 함수와 동일한 방식으로 텍스트를 암호화합니다. 결과로 생성된 암호문은 MySQL의 AES_DECRYPT 함수로 복호화할 수 있습니다. 동일한 입력에 대해서는 encrypt 함수와 동일한 암호문을 생성합니다. key 또는 iv가 일반적으로 필요한 길이보다 길 경우, aes_encrypt_mysql는 MySQL의 aes_encrypt와 동일하게 동작하여 key를 "fold"하고 iv의 초과 비트는 무시합니다.

지원되는 암호화 모드는 다음과 같습니다.

  • aes-128-ecb, aes-192-ecb, aes-256-ecb
  • aes-128-cbc, aes-192-cbc, aes-256-cbc
  • aes-128-ofb, aes-192-ofb, aes-256-ofb

구문

aes_encrypt_mysql(mode, plaintext, key[, iv])

인수

  • mode — 암호화 모드. String
  • plaintext — 암호화해야 하는 텍스트. String
  • key — 암호화 키. mode에서 요구하는 길이보다 긴 경우 MySQL 방식의 key folding이 수행됩니다. String
  • iv — 선택 사항. 초기화 벡터(Initialization Vector). 처음 16바이트만 사용됩니다. String

반환값

암호화된 바이너리 문자열. String

예시

동일한 입력 비교

-- Given equal input encrypt and aes_encrypt_mysql produce the same ciphertext:
SELECT encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv') = aes_encrypt_mysql('aes-256-ofb', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv') AS ciphertexts_equal;
┌─ciphertexts_equal─┐
│                 1 │
└───────────────────┘

긴 키 사용 시 암호화 실패

-- But encrypt fails when key or iv is longer than expected:
SELECT encrypt('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123');
Received exception from server (version 22.6.1):
Code: 36. DB::Exception: Received from localhost:9000. DB::Exception: Invalid key size: 33 expected 32: While processing encrypt('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123').

MySQL과의 호환성

-- aes_encrypt_mysql produces MySQL-compatible output:
SELECT hex(aes_encrypt_mysql('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123')) AS ciphertext;
┌─ciphertext───┐
│ 24E9E4966469 │
└──────────────┘

더 긴 IV를 사용해도 동일한 결과를 반환합니다

-- Notice how supplying even longer IV produces the same result
SELECT hex(aes_encrypt_mysql('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123456')) AS ciphertext
┌─ciphertext───┐
│ 24E9E4966469 │
└──────────────┘

decrypt

도입 버전: v20.12

이 FUNCTION은 AES로 암호화된 바이너리 문자열을 다음 모드로 복호화합니다:

  • aes-128-ecb, aes-192-ecb, aes-256-ecb
  • aes-128-cbc, aes-192-cbc, aes-256-cbc
  • aes-128-ofb, aes-192-ofb, aes-256-ofb
  • aes-128-gcm, aes-192-gcm, aes-256-gcm
  • aes-128-ctr, aes-192-ctr, aes-256-ctr
  • aes-128-cfb, aes-128-cfb1, aes-128-cfb8

구문

decrypt(mode, ciphertext, key[, iv, aad])

인자

  • mode — 복호화 모드. String
  • ciphertext — 복호화해야 하는 암호화된 텍스트. String
  • key — 복호화 키. String
  • iv — 초기화 벡터. -gcm 모드에서는 필수이며, 기타 모드에서는 선택 사항입니다. String
  • aad — 추가 인증 데이터. 이 값이 올바르지 않으면 복호화가 수행되지 않습니다. -gcm 모드에서만 동작하며, 다른 모드에서는 예외를 발생시킵니다. String

반환 값

복호화된 평문을 반환합니다. String

예시

암호화된 데이터를 올바르게 복호화하기

-- Re-using the table from the encrypt function example
SELECT comment, hex(secret) FROM encryption_test;
┌─comment──────────────┬─hex(secret)──────────────────────────────────┐
│ aes-256-gcm          │ A8A3CCBC6426CFEEB60E4EAE03D3E94204C1B09E0254 │
│ aes-256-gcm with AAD │ A8A3CCBC6426D9A1017A0A932322F1852260A4AD6837 │
└──────────────────────┴──────────────────────────────────────────────┘
┌─comment──────────────────────────┬─hex(secret)──────────────────────┐
│ aes-256-ofb no IV                │ B4972BDC4459                     │
│ aes-256-ofb no IV, different key │ 2FF57C092DC9                     │
│ aes-256-ofb with IV              │ 5E6CB398F653                     │
│ aes-256-cbc no IV                │ 1BC0629A92450D9E73A00E7D02CF4142 │
└──────────────────────────────────┴──────────────────────────────────┘

암호화된 데이터의 잘못된 복호화

SELECT comment, decrypt('aes-256-cfb128', secret, '12345678910121314151617181920212') AS plaintext FROM encryption_test
-- Notice how only a portion of the data was properly decrypted, and the rest is gibberish since either `mode`, `key`, or `iv` were different upon encryption.
┌─comment──────────────┬─plaintext──┐
│ aes-256-gcm          │ OQ�E
                             �t�7T�\���\�   │
│ aes-256-gcm with AAD │ OQ�E
                             �\��si����;�o�� │
└──────────────────────┴────────────┘
┌─comment──────────────────────────┬─plaintext─┐
│ aes-256-ofb no IV                │ Secret    │
│ aes-256-ofb no IV, different key │ �4�
                                        �         │
│ aes-256-ofb with IV              │ ���6�~        │
│aes-256-cbc no IV                │ �2*4�h3c�4w��@
└──────────────────────────────────┴───────────┘

encrypt

도입 버전: v20.12

다음 모드 중 하나를 사용하는 AES로 평문을 암호문으로 암호화합니다:

  • aes-128-ecb, aes-192-ecb, aes-256-ecb
  • aes-128-cbc, aes-192-cbc, aes-256-cbc
  • aes-128-ofb, aes-192-ofb, aes-256-ofb
  • aes-128-gcm, aes-192-gcm, aes-256-gcm
  • aes-128-ctr, aes-192-ctr, aes-256-ctr
  • aes-128-cfb, aes-128-cfb1, aes-128-cfb8

구문

encrypt(mode, plaintext, key[, iv, aad])

인수

  • mode — 암호화 모드. String
  • plaintext — 암호화할 텍스트. String
  • key — 암호화 키. String
  • iv — 초기화 벡터. -gcm 모드에서는 필수이며, 다른 모드에서는 선택 사항입니다. String
  • aad — 추가 인증 데이터(Additional Authenticated Data). 암호화되지는 않지만 복호화에 영향을 줍니다. -gcm 모드에서만 사용되며, 다른 모드에서는 예외를 발생시킵니다. String

반환 값

이진 문자열 형태의 암호문을 반환합니다. String

예제

암호화 예제

CREATE TABLE encryption_test
(
    `comment` String,
    `secret` String
)
ENGINE = MergeTree;

INSERT INTO encryption_test VALUES
('aes-256-ofb no IV', encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212')),
('aes-256-ofb no IV, different key', encrypt('aes-256-ofb', 'Secret', 'keykeykeykeykeykeykeykeykeykeyke')),
('aes-256-ofb with IV', encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv')),
('aes-256-cbc no IV', encrypt('aes-256-cbc', 'Secret', '12345678910121314151617181920212'));

SELECT comment, hex(secret) FROM encryption_test;
┌─comment──────────────────────────┬─hex(secret)──────────────────────┐
│ aes-256-ofb no IV                │ B4972BDC4459                     │
│ aes-256-ofb no IV, different key │ 2FF57C092DC9                     │
│ aes-256-ofb with IV              │ 5E6CB398F653                     │
│ aes-256-cbc no IV                │ 1BC0629A92450D9E73A00E7D02CF4142 │
└──────────────────────────────────┴──────────────────────────────────┘

GCM 모드 예제

INSERT INTO encryption_test VALUES
('aes-256-gcm', encrypt('aes-256-gcm', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv')),

('aes-256-gcm with AAD', encrypt('aes-256-gcm', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv', 'aad'));

SELECT comment, hex(secret) FROM encryption_test WHERE comment LIKE '%gcm%';
┌─comment──────────────┬─hex(secret)──────────────────────────────────┐
│ aes-256-gcm          │ A8A3CCBC6426CFEEB60E4EAE03D3E94204C1B09E0254 │
│ aes-256-gcm with AAD │ A8A3CCBC6426D9A1017A0A932322F1852260A4AD6837 │
└──────────────────────┴──────────────────────────────────────────────┘

tryDecrypt

도입 버전: v22.10

decrypt 함수와 유사하지만, 잘못된 키로 인해 복호화에 실패하면 NULL을 반환합니다.

구문

tryDecrypt(mode, ciphertext, key[, iv, aad])

인수

  • mode — 복호화 모드. String
  • ciphertext — 복호화해야 하는 암호화된 텍스트. String
  • key — 복호화 키. String
  • iv — 선택 사항. 초기화 벡터입니다. -gcm 모드에서는 필수이며, 다른 모드에서는 선택 사항입니다. String
  • aad — 선택 사항. 인증된 추가 데이터입니다. 이 값이 올바르지 않으면 복호화되지 않습니다. -gcm 모드에서만 동작하며, 다른 모드에서는 예외를 던집니다. String

반환 값

복호화된 String 값을 반환하거나, 복호화가 실패한 경우 NULL을 반환합니다. Nullable(String)

예제

테이블 생성 및 데이터 삽입

-- Let's create a table where user_id is the unique user id, encrypted is an encrypted string field, iv is an initial vector for decrypt/encrypt.
-- Assume that users know their id and the key to decrypt the encrypted field:
CREATE TABLE decrypt_null
(
    dt DateTime,
    user_id UInt32,
    encrypted String,
    iv String
)
ENGINE = MergeTree;

-- Insert some data:
INSERT INTO decrypt_null VALUES
('2022-08-02 00:00:00', 1, encrypt('aes-256-gcm', 'value1', 'keykeykeykeykeykeykeykeykeykey01', 'iv1'), 'iv1'),
('2022-09-02 00:00:00', 2, encrypt('aes-256-gcm', 'value2', 'keykeykeykeykeykeykeykeykeykey02', 'iv2'), 'iv2'),
('2022-09-02 00:00:01', 3, encrypt('aes-256-gcm', 'value3', 'keykeykeykeykeykeykeykeykeykey03', 'iv3'), 'iv3');

-- Try decrypt with one key
SELECT
    dt,
    user_id,
    tryDecrypt('aes-256-gcm', encrypted, 'keykeykeykeykeykeykeykeykeykey02', iv) AS value
FROM decrypt_null
ORDER BY user_id ASC
┌──────────────────dt─┬─user_id─┬─value──┐
│ 2022-08-02 00:00:00 │       1 │ ᴺᵁᴸᴸ   │
│ 2022-09-02 00:00:00 │       2 │ value2 │
│ 2022-09-02 00:00:01 │       3 │ ᴺᵁᴸᴸ   │
└─────────────────────┴─────────┴────────┘