※注意:本記事内での計測結果は記載の条件下によるものとなります。異なる環境においては異なる結果が予想されますのでご認識ください。
こんにちは。
株式会社ラクスにて、主に先行技術検証を担当している「技術推進課」という部署に所属している鈴木(@moomooya)です。
ラクスの開発部ではこれまで社内で利用していなかった技術要素を自社の開発に適合するか検証し、ビジネス要求に対して迅速に応えられるようにそなえる 「技術推進プロジェクト」というプロジェクトがあります。
このプロジェクトで「DBセキュリティ」にまつわる検証を行なったので、その報告を共有しようかと思います。
今回はDBセキュリティの中でも、DBデータの暗号化の話が中心となります。
ちなみに中間報告時点で公開した記事はこちらになります。
DBセキュリティについて
本記事におけるDBセキュリティ
カバーする範囲
本稿で扱う「DBセキュリティ」については入室管理、アカウント管理、権限管理、データ暗号化、アクセス監視といった部分を対象とし、中でも技術的な検証が必要になるデータ暗号化について検証を進めていきます。
これらは個人情報の保護に関する法律についてのガイドライン(通則編)にて10-6 技術的安全管理措置
として記述されています。
カバーしない範囲
「DBセキュリティ」の範囲として定義した通り、ウェブアプリケーション経由のセキュリティは扱いません。 なのでDBMSへの通常アクセスによるセキュリティに関しては対象外とします。
今回扱うデータ暗号化手法
今回の検証で扱ったデータ暗号化手法は以下のとおりです。
- ディスク暗号化
- DBのデータファイルが格納されているディスクごと暗号化
- LUKSを利用
- DB機能による透過的暗号化
- DBMS側でデータ入出力時に暗黙的に暗号化/復号化を行う
- NEC製のTransparent Data Encryption for PostgreSQLをPostgreSQL(以下、TDEforPG)に組み込んで利用
- 機能として列単位暗号方式(カラム指定で暗号化)と行単位暗号方式(指定テーブルの全カラムを暗号化)があるので両方検証
- プロプライエタリな製品なので詳細な計測結果は非公開とします
- アプリケーションによるデータ暗号化
- アプリケーションによりデータを暗号化してからDBMSに格納
- pgcryptoを利用
今回実施した検証内容
検証概要
今回の検証では暗号化処理による性能劣化度合いの計測を中心に取り組んでいきます。
計測方法としては、非暗号化環境と各種暗号化環境を構築し、それぞれの環境で同一の性能計測テストを実施、測定結果の差分を暗号化処理によって劣化した性能として見ていきたいと思います。
性能計測テストでは
- 参照系としてselect
- 暗号化カラムを条件にした場合
- 非暗号化カラムを条件にした場合
- 更新系としてinsert, update
を中心とした計測を行いました。
計測観点では
- 処理速度
- CPU負荷
- メモリ負荷
の観点で計測を行なっています。
比較した環境
- 非暗号化環境
- この環境での計測結果を基準値とする
- LUKS環境
- ディスク暗号化
- pgcrypto環境
- 暗号化カラムと非暗号化カラムが混在するテーブルを持つ
- TDEforPG(列暗号方式)
- 暗号化カラムと非暗号化カラムが混在するテーブルを持つ
- TDEforPG(行暗号方式)
- 全てのカラムが暗号化されたテーブルを持つ
各環境はAWS EC2上に作成しており、EC2起動テンプレートを用いて環境構築を行った。 非暗号化環境の起動テンプレートをベースとして、暗号化手法のみが差分となるように各環境の起動テンプレートを作ることで環境差異を暗号化手法のみとなるようにした。
共通した条件
AWS実行環境
- EC2 m4.xlarge
- EBS gp2 10GB
EC2で利用したインスタンスは性能が可変のTシリーズではなく、通常の汎用インスタンスであるMシリーズを利用しています。 ストレージについてはEBSの汎用SSD gp2を利用しています。
テストデータ
- 100万レコードのテーブル
- データの内容はランダムな値をデータとして格納
- データ型は整数、実数、テキスト、真偽値を持つ
テストデータとしては実際のサービスで利用したときの処理速度に近くなるようにある程度のデータを用意しました。
検証結果
暗号化処理が増えることにより数十%程度の性能劣化は想定していましたが、一部のパターンで注意すべき性能劣化を計測することができました。
ディスク暗号化ではほぼ性能劣化は見られなかった
LUKSによる暗号化環境では、今回計測した全ての項目で非暗号化環境とほぼ同じ性能結果になりました。 厳密には128bitでの暗号化時は劣化なし。256bitの場合は10%程度の劣化が見られる感じです。
LUKSについてはディスクパフォーマンスのベンチマークも行いましたが、こちらではランダムライトで性能劣化が見られましたが、それ以外は性能劣化はありませんでした。 しかし、ウェブ上で事例を探すとSAS HDDの場合にシーケンシャルI/Oが劣化したり、NVMe SSDの場合にCPU負荷が上がる事例がありました。 今回はgp2を利用しましたが、EBS gp3を利用していたらCPU負荷の増加があったかもしれません。
暗号化カラムへの操作
どの暗号化方式でも処理速度の劣化は発生しました。
特に注意する必要があるのはpgcryptoで、暗号化したカラムを条件にしたselectで7,600倍の処理速度の劣化が見られました。実測値として、非暗号化時の74ミリ秒に対して9.4分です。
TDEforPGの場合だと、行単位暗号化で4倍程度、列単位暗号化で2倍程度の劣化で済んでおり、性能面でかなり優位性があります。 暗号化カラムを条件とした検索が必要な場合はpgcryptoではなく、TDEforPGを選択する強い理由になると思います。
非暗号化カラムへの操作
pgcryptoに関しては非暗号化カラムを条件としたselectでも10〜20%程度の処理速度劣化の影響が見られました。
またpgcryptoではinsertでも75倍の処理速度劣化、updateでは25倍の処理速度低下が見られました。 これはインデックスが有効な状態ではそれぞれ、17倍、18倍程度まで軽減されることを確認できました。
TDEforPGを用いた場合は、行単位暗号化、列単位暗号化ともに若干影響はあるように見えましたが劣化は5〜10%程度であり、あまり問題ない範囲かと思われます。
CPU, メモリへの負荷
今回の検証においては、すべての操作で暗黙的に暗号化/復号化が行われるTDEforPGの行暗号化方式で、CPUの平均で30%程度、メモリピークで30%程度の負荷増加が見られました。
それ以外の暗号化手法については誤差程度の差しか観測できませんでした。
性能面以外の注意点
LUKSはバックアップ運用や、サーバー再起動時に注意が必要
性能面ではあまり心配のいらないLUKSですが、ディスク全体を暗号化する都合上LUKSヘッダーという領域を必要とします。 LUKSヘッダーが破損するとディスク全体が読めなくなるため、バックアップ運用にてLUKSヘッダーもバックアップ対象に含める必要があります。
また、サーバー再起動時には都度暗号化ディスクの再マウントが必要になります。自動化することが可能なので設定しておくと良いと思います。
まとめ
暗号化手法ごとの特徴
LUKS
Linuxの標準機能の一つとなっており、性能面への影響も少ないため導入しやすい。
ただしディスク暗号化のため、ストレージの盗難1にしか対処できず
- OSへの不正ログイン
- DBMSへの不正ログイン
が行われた場合には効果がない。
pgcrypto
PostgreSQLの公式モジュールとして提供されているため導入ハードルは低い。 また、アプリケーションでの暗号化となるため、
- ストレージ盗難
- OSへの不正ログイン
- DBMSへの不正ログイン
に対しても耐性をもつ。
しかし、性能面での影響は大きく、特に暗号化カラムを条件としたselectは非実用的に思える。
検索条件にならないような機微情報カラムをピンポイントで暗号化するようなケースが使い所となる。
実装面でもアプリケーションのDBアクセス部分の改修が必要になるためDB全体および広い範囲を暗号化するような用途には向かない。
TDEforPG
DBMS機能として動作する透過的暗号化機能なので
- ストレージ盗難
- OSへの不正ログイン
への対策となる。
性能面はpgcryptoよりも全体的に良好で、暗号化カラムを検索条件にしなければならないときには有力なソリューションとなる。
商用製品のためコスト面で何らかの対応が必要になるが、利用料金も極端に高額なわけではない2ため、昨今のセキュリティ意識の高まりを考慮すると現実的な落とし所を見つけられそうです。
導入するとしたら
ストレージ盗難対策なら
ストレージ盗難のリスクに対応するためであればLUKSはデメリットが少なく、導入ハードルは低いといえます。
マイナンバーなどの機微情報を保護するためなら
pgcryptoによるカラム単位での暗号化で良いと思います。検索条件にしなければ現実的な対応だと思います。
もし暗号化カラムを検索対象にする必要があるのであれば、TDEforPGの列単位暗号方式の導入を検討する必要があります。
DB全体の暗号化をするなら
ストレージ盗難対策までで良ければ先述の通りLUKSが良いと思います。
OSへの不正ログインまで対応するのであれば、TDEforPGの行単位暗号方式を用いた透過的暗号化の導入を検討することになります。
いかがでしたでしょうか。
思っていたよりもツールによって棲み分けができているように思えました。 技術選定の助けとなれば幸いです。