ゆう's Blog
MySQLの組み込み関数(AES_ENCRYPTなど)を用いて暗号化したデータを保存する

AES_ENCRYPT('データ', '鍵')

キーの長さ: AESではキーの長さが暗号化の強度に影響します。AES_ENCRYPTでは、使用するキーの長さに基づいて暗号化が行われますが、長さが16バイト、24バイト、32バイト(128ビット、192ビット、256ビット)である必要があります。

指定したキーがそれ以外の長さの場合、MySQLは自動的にキーを適切な長さに切り詰めたり、ゼロ埋めを行う場合があります。

キーの長さが正確に16、24、32バイトの場合は、何の調整も行われずそのまま使用されます。

ゼロ埋めや切り捨ては、意図しない暗号化結果を引き起こす可能性があるため、使用するキーは明示的に適切な長さで生成することが推奨されます。

MySQLのAES_ENCRYPT関数は、ECBモードを使用します。このモードは各ブロックを独立して暗号化するため、初期化ベクトルを必要としません。
ECBモードの欠点として、同じ平文が同じ暗号文になるという特徴があります。これにより、暗号のパターンが推測されやすくなるという弱点があります。

AES_ENCRYPT(str, key) を使った場合、暗号化されたデータのサイズは以下のように決まります:

AESのブロックサイズは 16バイト(128ビット)です。
暗号化する文字列のサイズが 16バイトの倍数でない場合、パディングによってサイズが増加します。
暗号化後のデータサイズ ≈ 元のデータサイズ + (16 - 元のデータサイズ % 16)(パディングを考慮)

MySQL 8.0以降では、AES_ENCRYPTとAES_DECRYPTでAES-GCMモードをサポートするようになり、このモードでは暗号化に初期化ベクトル(IV)が内部的に使用されます。ただし、IVをユーザーが直接指定することはできません。システムが自動で管理します。
MariaDBでは、AES-GCMモードはサポートされていません。

暗号文サイズ = 平文のサイズ(バイト) + IVサイズ(12バイト) + 認証タグサイズ(16バイト)

AES-GCM以外の暗号化モード(例: AES-CBC, AES-ECBなど)では、認証タグが生成されない。
AES-GCMではパディングは発生しない。

MySQLのAES_ENCRYPT()はバイナリデータとして暗号化結果を返すため、保存するときはVARBINARYを使うのが適切です。