これらの関数は、AES (Advanced Encryption Standard) アルゴリズムを使用してデータの暗号化および復号を行います。
鍵長は暗号化モードに依存し、-128-、-196-、-256- 各モードに対してそれぞれ 16、24、32 バイトです。
初期化ベクトル (initialization vector) の長さは常に 16 バイトであり、16 バイトを超える部分は無視されます。
HMAC
導入バージョン: v25.12
指定されたハッシュアルゴリズムと秘密鍵を使用して、指定されたメッセージの HMAC(ハッシュベースメッセージ認証コード)を計算します。
サポートされているハッシュアルゴリズムは次のとおりです:
- 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
構文
引数
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 を折りたたみ、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])
引数
戻り値
復号済みの文字列を返します。String
例
MySQL データの復号
-- 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行のセット (0.00秒)
SELECT aes_decrypt_mysql('aes-256-ofb', unhex('24E9E4966469'), '123456789101213141516171819202122', 'iviviviviviviviv123456') AS plaintext
┌─plaintext─┐
│ シークレット │
└───────────┘
aes_encrypt_mysql
導入バージョン: v20.12
MySQL の AES_ENCRYPT 関数と同じ方法でテキストを暗号化します。
生成された暗号文は、MySQL の AES_DECRYPT 関数で復号できます。
同じ入力に対しては、encrypt 関数と同じ暗号文を生成します。
key または iv が本来の長さより長い場合、aes_encrypt_mysql は MySQL の aes_encrypt と同様に動作し、key を折りたたんで利用し、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 固有のキー折り畳み処理が行われます。String
iv — 任意。初期化ベクトル。先頭 16 バイトのみが使用されます。String
戻り値
暗号文のバイナリ文字列。String
使用例
同一入力の比較
-- 同一の入力に対して、encryptとaes_encrypt_mysqlは同じ暗号文を生成します:
SELECT encrypt('aes-256-ofb', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv') = aes_encrypt_mysql('aes-256-ofb', 'Secret', '12345678910121314151617181920212', 'iviviviviviviviv') AS ciphertexts_equal;
┌─ciphertexts_equal─┐
│ 1 │
└───────────────────┘
長いキーを指定すると Encrypt が失敗する
-- ただし、keyまたはivが想定より長い場合、encryptは失敗します:
SELECT encrypt('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123');
サーバーから例外を受信しました (バージョン 22.6.1):
Code: 36. DB::Exception: localhost:9000 から受信しました。DB::Exception: 無効なキーサイズ: 33 が指定されましたが、32 が期待されています: encrypt('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123') の処理中。
MySQL 互換性
-- aes_encrypt_mysql は MySQL 互換の出力を生成します:
SELECT hex(aes_encrypt_mysql('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123')) AS ciphertext;
┌─ciphertext───┐
│ 24E9E4966469 │
└──────────────┘
IV を長くしても結果は同じ
-- より長いIVを指定しても同じ結果が得られることに注意
SELECT hex(aes_encrypt_mysql('aes-256-ofb', 'Secret', '123456789101213141516171819202122', 'iviviviviviviviv123456')) AS ciphertext
┌─ciphertext───┐
│ 24E9E4966469 │
└──────────────┘
decrypt
導入バージョン: 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
構文
decrypt(mode, ciphertext, key[, iv, aad])
引数
mode — 復号モード。String
ciphertext — 復号する暗号化されたテキスト。String
key — 復号用キー。String
iv — 初期化ベクトル。-gcm モードでは必須、それ以外では任意。String
aad — 追加認証データ。この値が正しくない場合は復号できません。-gcm モードでのみ有効で、それ以外では例外をスローします。String
戻り値
復号された平文を返します。String
例
暗号化データを正しく復号する
-- encrypt関数の例のテーブルを再利用
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
-- データの一部のみが正しく復号化され、残りは暗号化時に `mode`、`key`、または `iv` が異なっていたため判読不能になっていることに注意してください。
┌─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 — 追加認証データ。これは暗号化はされませんが、復号に影響します。-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 IV なし │ B4972BDC4459 │
│ aes-256-ofb IV なし、異なるキー │ 2FF57C092DC9 │
│ aes-256-ofb IV あり │ 5E6CB398F653 │
│ aes-256-cbc 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)
例
テーブルを作成してデータを挿入
-- user_idが一意のユーザーID、encryptedが暗号化された文字列フィールド、ivが復号化/暗号化のための初期ベクトルであるテーブルを作成します。
-- ユーザーは自分のIDと暗号化されたフィールドを復号化するためのキーを知っていることを前提とします:
CREATE TABLE decrypt_null
(
dt DateTime,
user_id UInt32,
encrypted String,
iv String
)
ENGINE = MergeTree;
-- データを挿入します:
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');
-- 1つのキーで復号化を試みます:
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 │ ᴺᵁᴸᴸ │
└─────────────────────┴─────────┴────────┘