🔐

アプリケーション側ではなく、データベース(MySQL)で機密情報を暗号化する。

2021/06/25に公開約1,200字

① 暗号化・復号化するための鍵を生成する。

基本的には、強固なパスワードであれば OK なんですが、 RANDOM_BYTES() 関数を利用することで MySQL が SSL ライブラリの乱数ジェネレータを使用して、パスワードを生成することができます。

Zsh
SELECT RANDOM_BYTES(16);
  # 引数は '16' 以上にする必要があります。
  # ただし、AES_ENCRYPT(), AES_DECRYPT() で使用する場合は、'16' 以上は無視されます。

② 機密情報を暗号化する。

Zsh
SELECT HEX(AES_ENCRYPT('値', 'パスワード'));

● 暗号化処理の流れ

  1. AES_ENCRYPT('値', 'パスワード') を実行して、入力された平文の値を暗号化します。
    ※ デフォルトでは、AES(128ビット) で暗号化されます。

  2. 鍵をデータベースに保存する場合は、 HEX() 関数を使用して 16進数の文字列に変換することで、文字列型のカラムに保存できます。

③ 暗号化した情報を復号化する。

Zsh
SELECT convert( AES_DECRYPT( UNHEX('値'), 'パスワード') USING '文字コード');

● 復号化処理の流れ

  1. 暗号化する際に、HEX() 関数で文字列に変換している場合は、UNHEX('値') を実行して型を元に戻します。

  2. AES_DECRYPT('値', 'パスワード') を実行して、復号化します。
    ※ このとき NULL が返された場合は、入力した値 または パスワードが間違っています。

  3. convert('値' USING '文字コード') で使用している文字コードに変換します。

④ データベース(MySQL)で暗号化処理をおこなう際の注意事項


こんな感じで、Ruby on Rails や Laravel などのアプリケーション側で暗号化するだけでなく、データベース側(MySQL)でも暗号化できることに気付き、まとめてみました。
以上のようなデメリットはありますが、ユーザー 一人ひとりに対して、異なる鍵で暗号化・復号化することができたり、ユーザー情報と鍵の情報を別々のデータベースやリージョンに分けて管理することもできます。

Discussion

ログインするとコメントできます