【これだけ】MySQLでのデータの暗号化【現役エンジニアが解説】

PROGRAM

今回はMySQLでのデータの暗号化について、事例を交えて簡単に解説していきます。

カラムの暗号化

カラム単位でデータを暗号化したい場合には、基本的にはアプリケーション側で暗号化してからデータベースに保存します。

例えば、以下のusersテーブルがあると仮定し、nameのカラムを暗号化したいとします。

user_id name
1 山田太郎
2 田中花子
3 小林一郎

このケースでは、以下のようにSQLを実行する段階で既にカラム単位でデータを暗号化させておきます。

INSERT INTO (user_id, name) VALUES(4,'hIryJzVlZZDmSKwIil1ZLA==')

ただし、暗号化後は元の文字列に比べて非常に長くなってしまうため、テーブル定義で文字数を制限している場合には注意が必要です。

INSERT文やUPDATE文の実行時に、アプリケーション側で暗号化する際には、phpであれば、openssl_encrypt関数等を使うと良いでしょう。

一方、取得する際はいつもどおりのSELECT文で問題ありません。

SELECT user_id, name FROM users;

しかし、そのままではnameのカラムが暗号化されていますので、openssl_encrypt関数で暗号化したものなら、openssl_decrypt関数で複合化してから表示するようにしましょう。

テーブルの暗号化

テーブル全体でデータを暗号化する場合には、MySQLには透過的テーブルスペース暗号化という便利な機能があるため、これを利用すると良いでしょう。

この機能を使えば、MySQL標準の機能で暗号化してデータを保持くれるため、アプリケーション側で面倒な暗号化/複合化の処理を行う必要がありません。

この機能を使うためには、まず準備としてMySQLで以下のコマンドを実行します。

mysql> INSTALL PLUGIN keyring_file SONAME 'keyring_file.so';

あとは暗号化するテーブルを作成する際に、ENCRYPTIONオプションを付けるだけです。

CREATE TABLE users (user_id INT PRIMARY KEY, name VARCHAR(50)) ENCRYPTION='Y';

既存のテーブルを暗号化する場合には、以下のようにALTER TABLEで変更することが可能です。

mysql> ALTER TABLE users ENCRYPTION='Y';

透過的テーブルスペース暗号化では、SELECTやINSERT時にアプリケーション側のプログラムを変える必要が特にないということが、大きなメリットの一つです。

ただし、MySQLが裏で自動的に暗号化や複合化の処理を行うことになるため、クエリのパフォーマンスは全体的に10%程度落ちることだけは留意しておく必要があります。

暗号化以外の方法

そもそもなぜデータの暗号化をするかと言えば、クラウド上にデータを持つ等のセキュリティリスクへの対応であることがほとんどだと思います。

そこまでしてデータをクラウド上に持つ必要がない場合、環境が用意できるのであれば、オンプレミスで社内サーバにデータを持っても良いと思います。

ただし、フロントをクラウド上のWebサーバから変更できない場合には、オンプレミス側でWebAPIを開発しなければならないと思いますので、工数が増えてしまいます。

暗号化とそれ以外の方法の大きな違いは、前者は流出する前提に立っていますが、後者は未然に防ぐことを目的としている点であり、それぞれスタンスが大きく異なります。

場合によっては、いずれも行わなければならないケースもありますが、データのセキュリティに関して工数を限りなく削減したいのであれば、SQLインジェクションに気をつけ、暗号化を行うことが次善の策と言えるでしょう。