このページは機械翻訳されています。英語の原文をお読みください。 English

IBSurgeon ライブラリ

Firebirdデータベースの暗号化の仕組み

(c) Alexey Kovyazin, IBSurgeon, Alex Peshkoff, Firebird Project, 2021

この記事は、ドイツのベルリンで開催されたFirebird Conference 2019でのワークショップ「データベース暗号化」の資料に基づいています。Firebirdデータベース暗号化がサーバーレベル、クライアントサイドでどのように機能するか、データベース暗号化の設定方法、さまざまなタイプのアプリケーション(Delphi、Java、.NET)からどのように使用するかについて説明します。この記事の例はIBSurgeon Firebird Encryption Framework(FEPF)に基づいていますが、現在利用可能な暗号化プラグイン実装の大半に適用できます。

目次:

  1. なぜデータベース暗号化が必要なのか(そして不要な場合)?
  2. Firebirdデータベース暗号化がサーバーサイドでどのように機能するか
  3. データベースのどの部分が暗号化されるのか?
  4. データページはいつ暗号化されるのか?
  5. 鍵の転送をどのように保護するか?
  6. Firebird暗号化がクライアントサイドでどのように機能するか
  7. ネイティブアプリケーション
  8. Javaアプリケーション
  9. .NETアプリケーション
  10. インストールと設定
  11. 暗号化の進行状況を追跡する方法
  12. まとめ

1. なぜデータベース暗号化が必要なのか(そして不要な場合)?

Firebirdデータベース暗号化はFirebird 3.0リリースで導入され(転送プロトコル暗号化とともに、これはしばしば本テーマと混同されます)、不正アクセスからデータを保護する能力を大幅に向上させました。しかし、これは万能薬ではなく、適切に使用するためにはその長所と短所を理解する必要があります。

この記事では、データベース暗号化の内部構造を基本レベルで考察し、Firebirdアプリケーションの開発者にデータベース暗号化がどのように機能するかについてのより良い理解を提供します。

では、なぜデータベース暗号化が必要なのでしょうか?

  1. 機密性の高い/価値のあるデータを含むデータベースを「物理的な」盗難から保護するため。侵入者が暗号化されたデータベースのコピーが入ったディスクを盗んだり、何らかの方法でデータベースファイルのコピーを入手した場合、適切な鍵がなければそこからデータを読み取ることはできず、またFirstAIDのようなリカバリソフトウェアを使用してデータを抽出することもできません。もちろん、これは暗号化アルゴリズムと計算能力に依存しますが、AES256を解読するには長すぎる時間か、高価すぎる計算リソースが必要になります。
  2. 暗号化鍵を持たない非承認アプリケーションからのデータベースアクセスを保護するため。例としては、
    • 非承認者が開発者ツールで直接アクセスし、機密情報(例:金銭取引)を変更すること、
    • ビジネスロジック(ストアドプロシージャやトリガーのテキスト)を変更または盗むこと。
  3. 事前入力されたデータを含むデータベースを、非承認アプリケーションによるエクスポートやアクセスから保護する。
  4. 各国政府が最近データ保護法(欧州のGDPR/DSVGO、ブラジルのLGPDなど)を導入し、個人データやその他の機密データに対するより高いレベルの保護を要求しており、暗号化は適切な保護手段の一つとして言及されています。

データベース暗号化が役に立たない場合は?

場合によっては、データベース暗号化の代わりにFirebirdのセキュリティおよび設定機能を使用する方が良いでしょう:

  • ネットワーク経由の物理的アクセスからデータベースを保護するには、ネットワークアクセスを設定する必要があります:つまり、ネットワーク共有フォルダを閉じる(Firebirdはデータベースファイルへのネットワーク共有アクセスを必要としないため)、セキュリティ権限を厳格化する(例えばLinuxでは、データベースファイルはユーザー「firebird」のみが読み書きアクセスできる必要があります)。
  • 特定のユーザーサブセットに対する特定のデータベースへのアクセスを制限するには、別のセキュリティデータベースを設定する方が簡単な解決策です。
  • データベースオブジェクト(テーブル、ストアドプロシージャ)へのアクセスを制限するには、Firebirdのセキュリティメカニズム(ユーザー、ロールなど)を使用する必要があります。

もちろん、上記の両方のリストは完全ではありませんが、データベース暗号化がいつ必要か、いつ不要かについての印象を与えてくれます。

2. Firebirdデータベース暗号化がサーバーサイドでどのように機能するか

Firebirdデータベース暗号化の内部詳細を見ていきましょう。サーバー部分から始めます。

2.1. データベースのどの部分が暗号化されるのか?

最初に考慮すべきことは、データベースのどの部分が暗号化されるのかということです。ご存知のとおり、Firebirdデータベースは「データベースページ」と呼ばれる等しいサイズの部分で構成されています。そのようなページにはいくつかのタイプがあり、各タイプは特定の目的を果たします。

以下に、主要なデータタイプを示す図があります:

図1. データベースページのタイプ

一部のページはユーザーデータを格納するために設計されており、他のページはトランザクションやページインベントリページなどのシステム情報を格納するために必要です(データベースページの詳細はこちらで入手可能)。

Firebirdデータベースが暗号化される場合、ユーザーデータを含むページのみが暗号化されます:データページ、インデックス、ジェネレータ、およびBLOB:

図2. ユーザーデータを含むデータベースページのみが暗号化されます

データベースメタデータ(ストアドプロシージャ、テーブル、ビュー、トリガー、ジェネレータ名など)は、暗号化を担当するエンジンの部分では「ユーザーデータ」と変わらず、暗号化されることに注意してください。

なぜシステムページは暗号化されないのでしょうか?主にパフォーマンス上の理由と、保護が必要な機密データを含まないという事実によるものです。

データベースヘッダーページは暗号化されません。暗号化に必要な情報(例えば、鍵名)が含まれているためです。

2.2. データページはいつ暗号化されるのか?

ユーザーが暗号化されたデータベースからSELECTを実行すると、データは暗号化されたファイルから読み取られますが、結果セットとともにアプリケーションのグリッドには非暗号化形式で届きます。

このプロセスの詳細を考えてみましょう:

図3. データベースページはいつ暗号化されるのか?

通常、プロセスはデータベースファイルからのデータベースページの一連の読み取りから始まり、それらはオペレーティングシステムのファイルキャッシュにキャッシュされます。

Firebirdはファイルキャッシュをバイパスして独自のキャッシュのみを使用するように設定することもできますが、デフォルトではファイルキャッシュが使用されます。

その後、Firebirdはページを読み取り、Firebirdページキャッシュ(firebird.confおよび/またはdatabases.conf、またはデータベースヘッダーページのDefaultDBCachePagesパラメータで定義されます)に配置します。

次に、キャッシュからのページが特定のSQLステートメント(この例ではSELECT)の結果セットに選択されます。

以下の図に詳細を示します:

図4. ページはFirebirdキャッシュとOSファイルキャッシュの間で暗号化されます

つまり、データベースページはOSファイルキャッシュで暗号化されますが、Firebirdページキャッシュには非暗号化で到着し、その逆も同様です。

暗号化/復号化を担当するFirebirdソフトウェアの部分は「暗号化プラグイン」と呼ばれます。著者に知られているプラグイン実装の大半はDbCryptと呼ばれているため、ここではDbCryptと呼びます。

以下の図では、Windows(DbCrypt.dll)とLinux(libDbCrypt.so)のバリアントを見ることができます:

図5. 暗号化プラグイン(DbCrypt)が暗号化/復号化を行っている

この図をしばらく見ていると、次の疑問がすぐに浮かんでくるでしょう:DbCryptはデータベースページを暗号化/復号化するための適切なキーをどのように取得するのか?

その答えは、キー管理のための別のプラグインがあるということです。

キー管理の一般的な名称はKeyHolderで、暗号化プラグイン(DbCrypt)のためのキーストレージ/管理機能として機能します。KeyHolderは、DbCryptが使用するキー管理のためのインターフェースを実装しています。

図6. DbCryptとKeyHolder

「キー管理」とはどういう意味か?

最も単純なケースでは、DbCryptはサーバー上のファイルからキーを読み取ることができます。ファイルは、単純なプレーンテキストファイルであり、「秘密の」場所やUSBスティックに隠すこともできますし、暗号化されたファイル(例えばWindows Crypto APIを使用するか、組み込みの内部キーを使用する)にすることもできます。

キーファイルには複数のキーを含めることができ、便利なように名前付きリストとして保存され、次のようになります(以下の例はIBSurgeonEncryption Frameworkから引用):

Code
Key=Red 0xec,0xa1,0x52,0xf6,0x4d,0x27,0xda,0x93,0x53,0xe5,0x48,0x86,0xb9,0x7d,0xe2,0x8f,0x3b,0xfa,0xb7,0x91,0x22,0x5b,0x59,0x15,0x82,0x35,0xf5,0x30,0x1f,0x04,0xdc,0x75,
Key=Green 0xab,0xd7,0x34,0x63,0xae,0x19,0x52,0x00,0xb8,0x84,0xa3,0x44,0xbd,0x11,0x9f,0x72,0xe0,0x04,0x68,0x4f,0xc4,0x89,0x3b,0x20,0x8d,0x2a,0xa7,0x07,0x32,0x3b,0x5e,0x74,

データベースが暗号化されると、そのヘッダーページは暗号化されずに残り、暗号化プラグインとキーの名前に関する情報を保存します。この情報は「gstat -h データベース名」コマンドで確認できます:

Code
Database header page information:
....
Creation date    Jan 11, 2017 15:12:20
Attributes       force write, encrypted, plugin DBCRYPT

Variable header data:
 Crypt checksum: MUB2NTJqchh9RshmP6xFAiIc2iI=
 Key hash:       ask88tfWbinvC6b1JvS9Mfuh47c=
 Encryption key name:    RED
 Sweep interval:         0
*END*

DbCryptは複数のデータベースと複数のキーのページを処理できます:

図7. 同じサーバー(つまりFirebirdインスタンス)上の複数のデータベースに対する複数のキー

正しいキーの選択

開発者からよく寄せられる質問は「プラグインはどのキーがどのデータベース用かをどのように認識するのか?」というものです。答えは非常に簡単です:データベースのヘッダーページに保存されているキー名によって認識します。

あまり頻繁ではありませんが、重要な質問もあります - キー名がヘッダーに記録されているものと同じでも、キーの値が異なる場合はどうなるのか? 誤ったキーによるページ読み取りエラーを防ぐために、DbCryptプラグインは暗号化されたテストシーケンス(数字0…F)をヘッダーに保存し、キーがアクティブ化されると、プラグインはサンプルデータをキーで暗号化し、そのハッシュを保存された結果と比較して、渡されたキー値が実際にこの特定のデータベースに対して正しいことを確認します。

暗号化プラグインがキーを直接読み取るアプローチは、透過的な方法で暗号化を実装するため、デバッグ、パフォーマンステストなどにシンプルで有益です:つまり、クライアントアプリケーションや開発者ツールはデータベースが暗号化されていることを知りません。

しかし、実際には、アプリケーションのデータベースへのアクセスを制限する必要があります:キーを持つクライアントアプリケーションだけが暗号化されたデータベースに接続できるようにする必要があります。

このために、KeyHolderプラグインが必要です。Firebirdネットワークプロトコルを通じてクライアントアプリケーション(通常は別のコンピューター上にある)からキーを取得します。

2.3. キーの転送をどのように保護するか?

顧客が承認されたアプリケーションを迂回して暗号化されたデータベースに直接アクセスすることを決定した状況で、データベースを保護したい場合があります(多くのベンダーは、読み取り専用または読み書きのいずれかで、直接アクセスからデータを制限したいと考えています)。

これは、侵入者がサーバーにアクセスできるがキーを持っていない状況と同等です。

サーバー側でキーを傍受するための以下の攻撃シナリオを考えてみましょう:

  1. 侵入者が偽の暗号化プラグイン(DBCrypt.dll)を作成してサーバーに配置し、KeyHolderがキーを渡すときに、偽のDbCryptがキーのダンプを作成する場合:

図8. 偽のDbCrypt.dllによる攻撃

  1. 侵入者が偽のfirebird.exeファイルを作成し、それでダンプを作成する場合:

図9. 偽のfirebird.exeによる攻撃

このような攻撃から保護するために、暗号化およびキー管理プラグインの優れた実装は、キー交換を保護する必要があります。

キー交換は、公開鍵/秘密鍵のペアを使用した非対称暗号化で保護できます。

これらのキーはビルドプロセス中に生成され、特定の暗号化プラグインとキー管理プラグインのペアに組み込まれます。最良の保護のためには、特別に構築されたDbCrypt/KeyHolderのペアを使用する必要があります。

DbCryptとKeyHolderがキーを交換するとき、次のプロトコルを使用します(簡略化されていますが、考え方は明確だと思います):

Code
DbCrypt → KeyHolder:
	このソルトでデータベースキーを渡せ
KeyHolder:
	DbCryptからのソルトを使用して公開鍵でDbKeyを暗号化する
	暗号化されたDbKeyをDbCryptに転送する
DbCrypt:
	秘密鍵でDbKeyを復号化する
	ソルトの正確性を検証する
	作業準備完了

ほぼ同じプロトコルが、KeyHolderのインスタンス間のキー交換、およびクライアントアプリケーションとKeyHolder間のキー交換にも使用されます。

転送されるキーの暗号化と正確性はプラグインの実装に依存することに注意してください。Firebirdエンジンは「このプラグインインスタンスからそのプラグインインスタンスへNバイトを送信する」という基本的な低レベル転送サービスのみを提供します。

暗号化のサーバー側部分のまとめ

  • 暗号化/復号化は、データベース暗号化プラグイン(DbCrypt)によって、オペレーティングシステムのファイルキャッシュとFirebirdページキャッシュ間のデータ交換中にページごとに実行されます
  • キー管理は、DbCryptがキーを直接読み取る単純な方法で実装できますが、通常はキー管理プラグイン(KeyHolder)で行われます

次に、クライアントアプリケーションが暗号化されたデータベースでどのように動作するかを見てみましょう。

3. Firebird暗号化がクライアント側でどのように機能するか

3.1. ネイティブアプリケーション

クライアントアプリケーションが暗号化されたデータベースに接続するときに何が起こるかを理解するために、ネイティブアプリケーションの非暗号化データベースへの通常の接続プロセスを考えてみましょう。

注意:ここから以降、「ネイティブ」とは、そのようなアプリケーションがfbclient.dllを使用してサーバーとのネットワーク接続を確立することを意味します。通常、そのようなアプリはDelphi、C++、PHPで構築されています。ネイティブアプリケーションとは異なり、Javaと.NETは独自のバージョンのプロトコルを実装しており、これらは以下で説明します。

接続プロセス:

  1. クライアントアプリケーションがクライアントライブラリをロードします
  2. fbclient.dll - ネイティブWindowsアプリ
  3. libfbclient.so - ネイティブLinuxアプリ
  4. クライアントアプリケーションが接続を開始し、送信します
  5. ユーザー名(例:SYSDBA)
  6. パスワード(例:masterkey)
  7. データベースのパス/エイリアス

暗号化されたデータベースの場合、追加のステップが必要です:暗号化キーの名前とその値を渡す必要があります。

キーの受け渡しは通常の接続の前に行う必要があることに注意することが重要です。これは、データベース所有者名、文字セットなどを含むメタデータを持つデータページが暗号化されているためです。

したがって、次のことが導き出されます:

  1. 通常の接続の前にキーを渡すために追加のネットワークラウンドトリップが必要です
  2. クライアントアプリケーションからFirebirdへのキー転送には、非対称暗号化の使用とコールバックインターフェースの実装が必要であり、かなり複雑になる可能性があります。このタスクを簡素化するために、プラグインベンダーは接続するためのコードの例を提供するか、IBSurgeonプラグインフレームワークのように、クライアントアプリケーションからキーを転送するための使いやすい適切なインターフェースを実装する追加ライブラリfbcrypt.dll/libfbcrypt.soを作成します。

ネイティブアプリケーション(fbclient.dllを使用する)を暗号化データベースに接続するには、3つの呼び出しを行う必要があります。以下はDelphiの例です(簡略化されており、エラーハンドリングはありません):

BeforeConnectイベントハンドラ内:

Code
fbcrypt_init(PAnsiChar(‘C:\Firebird30.bclient.dll’));
fbcrypt_key(‘RED’, ‘0xec,0xa1,0x52,0xf6,...’));
fbcrypt_callback(nil);

 // その後、通常どおり接続します
Database1.Active:=True;

下の図は、ネイティブアプリケーションで暗号化データベースに接続するプロセスの概要を示しています:

図10. ネイティブアプリケーションの暗号化データベースへの接続プロセス

マルチスレッドのクライアントアプリケーションの場合、スレッドセーフティはどうなりますか?

マルチスレッドのクライアントアプリケーションの実装に関する一般的なポイントをいくつか思い出させてください。

Firebird 2.5以降、アプリケーション内の複数のスレッドは、データベースへの単一のアタッチメントを安全に使用できます。これは、必要な同期がすべてfbclient.dll内で行われるためです。

ただし、この場合、スレッドはアタッチメントを1つずつしか使用できません。

これは、データベースとの高性能なデータ交換を必要としないアプリケーションには問題ありません。あるスレッドが別のSQLを実行しているときに、別のスレッドからSQLクエリを実行するのを待つことが問題にならない場合は、1つのアタッチメントを複数のスレッドで共有する単純なモデルを使用する方が簡単です。

アプリケーションがSQLクエリを並列実行する必要がある場合(つまり、本格的なクライアントアプリケーションの場合)、接続ごとに個別のスレッドを使用する方が適しています。

暗号化データベースへのアタッチメントのキー交換の状況は、もう少し複雑です。

アタッチメントのたびに、クライアントライブラリはクライアントからキーを転送しますが、これはクライアントアプリケーションのスレッドに直接関連しているわけではなく、状況は使用されるAPIに依存します。

ご存知のように、Firebirdクライアントライブラリは3.0以降、2種類のAPIを提供しています:プロバイダーの概念に基づく新しいオブジェクト指向APIと、古いFirebirdドライバーとの互換性を維持するための回避策として実装されたレガシーisc_ APIです。

新しいオブジェクト指向クライアントAPIが使用される場合、プロバイダーを作成し、必要なキーを供給してから、新しいアタッチメントに使用するだけで十分です。

isc_クライアントAPIが使用される場合、アタッチメントごとにクライアントライブラリは独自の一時プロバイダーを作成しますが、これはエンドユーザーからは直接見えず、アクセスもできません。

この場合、キーはisc_attach_databaseが呼び出されたスレッドから正確に転送され、そのキーを格納するためにスレッドローカルストレージが使用されます。

実際には、ほとんどすべてのクライアントライブラリがisc_ APIを使用しているため(現時点では、人気のあるドライバーの中でOO APIを使用しているのはPythonドライバーのみです)、暗号化データベースに接続する各スレッドでfb_database_crypt_callback()を呼び出す必要があります。

キー転送呼び出し(FEPFの例でのfbcrypt.dll呼び出し)は、接続が確立される同じスレッドで、接続の前に行う必要があります。

多くのデータベースを扱う場合(たとえば、多数のクライアントデータベースを持つSaaS Webサーバー)、fbcrypt_key()を呼び出すたびに、現在の接続に関連付けられたKeyHolderストレージにキーが追加されることを覚えておくことが重要です。

キー値は接続の前に設定する必要があり、アタッチメント後はキー値を変更できません。

デタッチの場合、キーはアンロードされず、fbcrypt.dllがアンロードされるまでメモリに保持されます。

3.2. Javaアプリケーション

Javaドライバー(JayBird)には、Firebird接続プロトコルの独自の実装(純粋なJava)があります。Jaybird 4(および3.0.4以降)は、バージョン13プロトコルの純粋なJava実装でFirebird 3データベース暗号化コールバックのサポートを追加します。

Jaybird 4 Readmeより:

現在の実装は単純で、接続プロパティからの静的値での応答のみをサポートしています。データベース暗号化に対する静的値の応答は、リプレイ攻撃や意図しないキー露出につながる可能性があるため、あまり安全ではないことに注意してください。

Jaybirdの将来のバージョン(おそらく5)では、より複雑なコールバックを必要とするデータベース暗号化プラグインのプラグインサポートが導入される予定です。

実際には、接続プロパティdbCryptConfigに暗号化コールバックの値(通常はキー名とキーと値のペア)を設定する必要があることを意味します。

例:

Code
 edConnectionString.setText("jdbc:firebirdsql://localhost/g:/Databases/ODS12/crypt.fdb?lc_ctype=utf8&dbCryptConfig=MyKey:0xec,0xa1,0x52,0xf6,0x4d,0x27,0xda,0x93,0x53,0xe5,0x48,0x86,0xb9,0x7d,0xe2,0x8f,0x3b,0xfa,0xb7,0x91,0x22,0x5b,0x59,0x15,0x82,0x35,0xf5,0x30,0x1f,0x04,0xdc,0x75,");

base64で文字列を指定することも可能です - readmeより:

base64::で始まる文字列は、残りの文字列がbase64としてバイトにデコードされます。

=パディング文字はオプションですが、存在する場合は有効である必要があります(つまり、パディングを使用する場合は、長さに対して正しい数のパディング文字を使用する必要があります)。

base64でエンコードされた値に+が含まれる場合、JDBC URLでは%2Bとしてエスケープする必要があります。Jaybird 3との後方互換性のため、URLセーフなbase64バリアントに切り替えることはできません。

IBSurgeonのキー管理プラグインの実装では、このようなキーの送信は多かれ少なかれ安全ではないと見なされます:ネットワークプロトコル暗号化が有効でない場合( ちなみに、有効にするには、firebird.confでWireCrypt=Requiredを設定し、レガシー認証を使用しないでください)、キーはWireSharkなどのネットワークトラフィックアナライザーで簡単に検出できます。したがって、この方法でキーの送信を有効にするには、IBSurgeonキー管理プラグインのKeyHolder.confでUnsafeClient=trueを設定する必要があります。

3.3 .NETアプリケーション

Firebird.NETプロバイダーは、暗号化データベースのキー交換の同様のスキームを実装しており、FEPFのKeyHolder.confでパラメータUnsafeClient=trueを設定する必要もあります。

暗号化データベースの接続文字列の.NETの例:

Code
string connectionString =
                "User=SYSDBA;" +
                "Password=masterkey;" +
                "Database=G:\\Databases\\ODS12.RYPT.FDB;" +
                "DataSource=localhost;" +
                "Port=3053;" +
                "Dialect=3;" +
                "Charset=NONE;" +
                "Role=;" +
                "Connection lifetime=15;" +
                "Pooling=true;" +
                "MinPoolSize=0;" +
                "MaxPoolSize=50;" +
                "Packet Size=8192;" +
                "ServerType=0;" +
                 "cryptkey = TXlLZXk6MHhlYywweG…...;";

暗号化キーがネイティブアプリケーションやJayBirdの例とは異なって見えることに気づくでしょう。これはBase64変換の結果であるため、.NETまたはJavaアプリケーション用のキーを取得するには、次の文字列からbase64を計算する必要があります:

“MyKey:0xec,0xa1,0x52,0xf6,0x4d,0x27,0xda,0x93,0x53,0xe5,0x48,0x86,0xb9,0x7d,0xe2,0x8f,0x3b,0xfa,0xb7,0x91,0x22,0x5b,0x59,0x15,0x82,0x35,0xf5,0x30,0x1f,0x04,0xdc,0x75,”

そして、接続文字列の最後に「;」を付けて「cryptkey=xxx;」のパラメータとして使用します。

4. インストールと設定

データベース暗号化とキー管理プラグインを有効にするには、Firebird設定ファイルfirebird.confで暗号化プラグインの名前を指定する必要があります:

Code
 KeyHolderPlugin = KeyHolder

または、代わりに、databases.confで暗号化データベースのエイリアスに対して:

Code
myencrypted = C:\Temp\EMPLOYEE30.MPLOYEE30.FDB { KeyHolderPlugin = KeyHolder }

次に、プラグインに必要なすべてのファイルがサーバー上にあることを確認する必要があります。

以下の例はIBSurgeonのFEPF用ですが、他のプラグインも多かれ少なかれ似ています:

%FirebirdFolder$\plugins内

Code
    • DbCrypt.dll
    • DbCrypt.conf
    • KeyHolder.dll
    • KeyHolder.conf - デバッグモードのみ!

**%FirebirdFolder$ 内**
• fbcrypt.dll
• libcrypto-1_1-x64.dll
• libssl-1_1-x64.dll
• firebird.msg
Code

その後、サーバー上でテスト暗号化を実行できます。これには、isql で次のようにします:

isql.exe localhost:C:\Temp\EMPLOYEE30.MPLOYEE30.FDB -user SYSDBA -pass masterkey SQL>alter database encrypt with dbcrypt key red; SQL> show database; Database: localhost:C:\Temp\EMPLOYEE30.MPLOYEE30.FDB …. ODS = 12.0 Database encrypted Default Character set: NONE

Code

Linux を使用している場合は、大文字と小文字が区別されることに注意してください。コマンドは次のようになります:

alter database encrypt with “DbCrypt” key Red;

Code

次に、暗号化されたデータベースへのクライアントアクセスをテストできます。これを行うには、設定ファイル KeyHolder.conf を削除(または名前変更、編集)し、簡単なテストアプリケーションで暗号化されたデータベースへの接続を試みます。

このためには、クライアントアプリケーションのフォルダーに次のファイルを配置する必要があります:

- [FEPF](/ja/download-demo-firebird-encryption-plugin) のデモアプリ - CryptTest.exe (32bit)
- 必須ファイル:
  - fbclient.dll
  - fbcrypt.dll
  - libcrypto-1.1.dll
  - libssl-1.1-x64.dll
- オプションファイル:
  - firebird.conf
  - plugins 内
    - ◦ KeyHolder.conf
    - ◦ keyhodler.dll

キー管理プラグインの一部の実装では、クライアントソフトウェアを変更せずに、[クライアントライブラリ(fbclient.dll)にキーをロードする](/ja/download-demo-firebird-encryption-plugin#Connect%20Firebird%20database%20with%20developer%20tools)ことが可能です。

これにより、Firebird 開発者ツール(Firebird SQL Studio、DatabaseWorkbench、IBExpert、FlameRobin、RedExpert など)の透過的な動作と、Firebird コマンドラインツール(gfix.exe、nbackup.exe など)の透過的な使用が可能になります。

## 5. 暗号化の進行状況を追跡する方法

Firebird は、アクティブな接続がある場合にのみデータベースを暗号化します。暗号化プロセスは別の並列スレッドで実行され、大規模なデータベースの場合、完全な暗号化にはかなりの時間がかかる可能性があります。

暗号化プロセスを追跡するには、MON$ から SQL クエリを実行するか:

select mon$crypt_page * 100.0 / mon$pages as Percent from mon$database; commit;

Code

または、特別なスイッチを指定して gstat ツールを実行します:

gstat -e dbname

Database “D:\ENCDB\TESTENCRYPT.FDB” Gstat execution time Tue Mar 16 11:45:11 2021

Database header page information: Flags 0 Generation 10697 System Change Number 3 Page size 8192 ODS version 12.0 Oldest transaction 7053 Oldest active 7054 Oldest snapshot 7054 Next transaction 7054 Sequence number 0 Next attachment ID 17834 Implementation HW=Intel/i386 little-endian OS=Windows CC=MSVC Shadow count 0 Page buffers 0 Next header page 0 Database dialect 3 Creation date Oct 9, 2019 6:42:31 Attributes encrypted, plugin DBCRYPT

Variable header data:
    Database backup GUID:   {866B4967-ED58-427E-A481-DB9206CEA2ED}
    Crypt checksum: MUB2NTJqchh9RshmP6xFAiIc2iI=
    Key hash:       ask88tfWbinvC6b1JvS9Mfuh47c=
    Encryption key name:    RED
    Database GUID:  {323FE494-1771-4608-E99D-C1B69C84578B}
    *END*

Data pages: total 105, encrypted 105, non-crypted 0 Index pages: total 95, encrypted 95, non-crypted 0 Blob pages: total 0, encrypted 0, non-crypted 0 Generator pages: total 1, encrypted 1, non-crypted 0 Gstat completion time Tue Mar 16 11:45:11 2021

Code

gstat の実行には時間がかかる場合があることに注意してください。

## 6. まとめ

1. Firebird データベース暗号化は、データベース内の情報を不正アクセスから保護するための強力な機能です。
2. 暗号化プロセスには、サーバー側の動的ライブラリ(暗号化プラグイン、通常は DbCrypt と呼ばれる)と、ほとんどの場合、キー管理プラグイン(通常は KeyHolder と呼ばれる)が必要です。
3. DbCrypt および KeyHolder プラグインの安全で信頼性の高い実装は、最も一般的な攻撃タイプを考慮して行う必要があります。
4. 暗号化されたデータベースを操作するには、クライアントアプリケーションが暗号化キーを転送する必要があります。
5. サーバー側での暗号化プラグインのインストールと設定は簡単で、firebird.conf/databases.conf の 1 つのパラメーターと数個のファイルが必要です。
6. 暗号化プロセスには時間がかかる場合があり、別のバックグラウンドスレッドで実行されます。進行状況は MON$ 呼び出しまたは gstat で確認できます。

### 次のステップ:

私たちは Firebird データベース暗号化の詳細なパフォーマンステストに取り組んでいます。一般的に、パフォーマンスは 4〜8% 低下しますが、ハードウェアと Firebird の設定によって異なります。ご期待ください!

### お問い合わせ:

ご提案、タイプミス、エラーなどのご指摘、およびご質問は、メールでお送りください:[[email protected]](mailto:[email protected]?subject=Firebird%20Db%20encryption%20article)