すべてのプロダクト
Search
ドキュメントセンター

PolarDB:透明なデータ暗号化

最終更新日:Jun 27, 2024

このトピックでは、保存中のデータを暗号化し、潜在的な攻撃者からディスク上の機密データベースファイルを保護する透過的なデータ暗号化 (TDE) について説明します。

前提条件

PolarDB for PostgreSQL (Oracle互換) クラスターは、次のいずれかのエンジンを実行します。

Oracle 2.0 (バージョン2.0.14.1.1以降)

説明

次のステートメントを実行して、 PolarDB for PostgreSQL (Compatible with Oracle) クラスターのリビジョンバージョンを照会できます。

SHOW polar_version; 

背景情報

中国では、インターネット上の情報セキュリティを保護するために、関連するサービスプロバイダーはデータセキュリティ基準を満たす必要があります。 そのような基準は次のとおりです。

  • 中華人民共和国暗号法 (2020年1月1日発効)

  • 情報セキュリティ技術-サイバーセキュリティの分類保護のベースライン (GB/T 22239-2019)

産業および地域の組織は、次のようなデータセキュリティ基準も導入しています。

  • ペイメント カード業界データ セキュリティ基準 (PCI-DSS)

  • 健康保険の相互運用性と説明責任法 (HIPAA)

  • 一般データ保護規則 (GDPR)

  • カリフォルニア州消費者保護法 (CCPA)

  • サーベンスオクスリー法 (SOX)

データセキュリティ保護の要件を満たすために、PolarDBはTDE機能を提供しています。 TDEを使用すると、認証されたユーザーは、復号化のためにアプリケーションコードや設定を変更することなく、暗号化データにアクセスできます。 オペレーティングシステムからテーブルスペースまたはディスクおよびデータベースバックアップの機密情報にアクセスする不正な試行を停止します。

用語

期間

説明

キー暗号化キー (KEK)

別のキーの暗号化に使用されるキー。

メモリデータ暗号化キー (MDEK)

データの暗号化に使用され、メモリに保存されるキー。 pg_strong_random関数を使用してランダムに生成されます。

テーブルデータ暗号化キー (TDEK)

テーブルデータの暗号化に使用され、メモリに保存されるキー。 これは、HKDFアルゴリズムを使用してMDEKから生成される。

WALデータ暗号化キー (WDEK)

WALログの暗号化に使用されるキー。 これは、HKDFアルゴリズムを使用してMDEKから生成される。

鍵のハッシュベースのメッセージ認証コード (HMACK)

KEKと共に、パスフレーズからのSHA-512を使用してHMACKが生成される。

鍵暗号化鍵のハッシュベースのメッセージ認証コード (KEK_HMAC)

キーの復号化中に使用される認証情報。 これは、HMACアルゴリズムを使用してENCMDEKおよびHMACKから生成される。

メモリデータ暗号化キーのエンコード (ENCMDEK)

データの暗号化に使用され、メモリに保存されるキー。 これは、KEKでMDEKを暗号化することによって生成される。

TDEのしくみ

  • キー管理モジュール

    • キー構造

      TDEは、KEKとTDEKで構成される2層のキー構造を使用します。 TDEKはデータベースデータを暗号化するために使用され、KEKはTDEKを暗号化するために使用される。 2層キー構造の詳細な説明は次のとおりです。

      • KEKおよびHMACK: 最初の32バイトをKEKとし、最後の32バイトをHMACKとする64バイトのデータ。 これは、polar_cluster_passphrase_commandパラメーターで指定されたコマンドを実行した出力にSHA-512アルゴリズムを適用することによって生成されます。

      • TDEKおよびWDEK: データおよびWALログ暗号化のための鍵であり、暗号的に安全な乱数発生器を使用して生成される。 2つの鍵を使用して暗号化された暗号文は、RDEK_HMACおよびWEDK_HMACを生成するために、HMACKおよびHMACアルゴリズムでさらに暗号化される。 RDEK_HMACとWEDK_HMACはKEK検証に使用され、共有ストレージに保存されます。

      KEKおよびHMACKは、鍵管理サービス (KMS) などの外部システムから常に取得される。 テスト中に、echo passphraseコマンドを実行して2つのキーを取得できます。 ENCMDEKとKEK_HMACは共有ストレージに保存して、プライマリノードと読み取り専用ノードが次回の起動時にキーファイルを読み取り、データ暗号化キーを取得できるようにする必要があります。 データ構造は次のとおりです。

      typedef struct KmgrFileData
      {
          /* version for kmgr file */
          uint32      kmgr_version_no;
      
          /* Are data pages encrypted? Zero if encryption is disabled */
          uint32      data_encryption_cipher;
      
          /*
           * Wrapped Key information for data encryption.
           */
          WrappedEncKeyWithHmac tde_rdek;
          WrappedEncKeyWithHmac tde_wdek;
      
          /* CRC of all above ... MUST BE LAST! */
          pg_crc32c   crc;
      } KmgrFileData;

      このファイルは, initdbコマンドの実行中に生成されます。 これにより、スタンバイとして機能する読み取り専用ノードがpg_basebackupを使用してファイルを取得できるようになります。

      クラスターの実行中、TDE関連の制御情報はプロセスメモリに次の構造で保存されます。

      static keydata_t keyEncKey[TDE_KEK_SIZE];
      static keydata_t relEncKey[TDE_MAX_DEK_SIZE];
      static keydata_t walEncKey[TDE_MAX_DEK_SIZE];
      char *polar_cluster_passphrase_command = NULL;
      extern int data_encryption_cipher;
    • キー暗号化

      データベースの初期化中にキーを生成する必要があります。 次の図は、プロセスを示しています。密钥加密

      1. polar_cluster_passphrase_commandパラメーターで指定されたコマンドを実行し、32バイトのKEKと32バイトのHMACKを取得します。

      2. OpenSSLの乱数生成アルゴリズムを使用してMDEKを生成します。

      3. OpenSSLのHKDFアルゴリズムを使用して、MDEKからTDEKを生成します。

      4. OpenSSLのHKDFアルゴリズムを使用して、MDEKからWDEKを生成します。

      5. KEKでMDEKを暗号化してENCMDEKを生成します。

      6. HMACアルゴリズムを使用して、ENCMDEKとHMACKからKEK_HMACを生成します。 KEK_HMACは、鍵復号中の検証に使用される。

      7. KmgrFileData構造体のENCMDEK、KEK_HMAC、およびその他の補足情報をglobal/kmgrファイルに書き込みます。

    • キーの解読

      データベースのクラッシュまたは再起動の場合は、限られた暗号文情報に基づいて対応するキーを復号化する必要があります。 次の図は、プロセスを示しています。密钥解密

      1. global/kmgrファイルを読み取り、ENCMDEKおよびKEK_HMACを取得します。

      2. polar_cluster_passphrase_commandパラメーターで指定されたコマンドを32バイトのKEKと32バイトのHMACKに実行します。

      3. HMACアルゴリズムを使用して、ENCMDEKとHMACKからKEK_HMAC 'を生成します。 KEK_HMACとKEK_HMAC 'が同じかどうかを確認します。 そうであれば、次のステップに進む。 そうでない場合は、エラーを返します。

      4. KEKを使用してENCMDEKを復号し、MDEKを生成します。

      5. OpenSSLのHKDFアルゴリズムを使用して、MDEKからTDEKを生成します。 情報が変化しないので、同じTDEKを生成することができる。

      6. OpenSSLのHKDFアルゴリズムを使用して、MDEKからWDEKを生成します。 情報が変更されないので、同じWDEKを生成することができる。

    • キーの交換

      キー置換は、古いKEKでキーを解読し、新しいKEKで新しいグローバル /kmgrファイルを生成するプロセスです。 次の図は、プロセスを示しています。密钥更换

      1. 古いglobal/kmgrファイルを読み取り、ENCMDEKおよびKEK_HMACを取得します。

      2. polar_cluster_passphrase_commandパラメーターで指定されたコマンドを実行して、32バイトのKEKと32バイトのHMACKを生成します。

      3. HMACアルゴリズムを使用して、ENCMDEKとHMACKからKEK_HMAC 'を生成します。 KEK_HMACとKEK_HMAC 'が同じかどうかを確認します。 そうであれば、次のステップに進む。 そうでない場合、エラーが返される。

      4. 古いKEKを使用してENCMDEKを復号し、MDEKを生成します。

      5. polar_cluster_passphrase_commandパラメーターで指定されたコマンドを実行して、新しいKEKと新しいHMACKを取得します。

      6. 新しいKEKを使用してMDEKを暗号化し、新しいENCMDEKを生成します。

      7. HMACアルゴリズムを使用して、新しいENCMDEKと新しいHMACKから新しいKEK_HMACを生成します。 新しいKEK_HMACは、鍵復号中の検証に使用される。

      8. 新しいENCMDEK、新しいKEK_HMAC、およびKmgrFileData構造のその他の補足情報をglobal/kmgrファイルに書き込みます。

  • 暗号化モジュール

    すべてのユーザーデータは、ページレベルでAES-128またはAES-256暗号化アルゴリズムを使用して暗号化されることが期待されます。 AES-256はデフォルトで使用されます。 (ページLSN、ページ番号) は、各データページの暗号化のための初期ベクトル (IV) として使用される。 IVは、同じコンテンツから異なる暗号化結果を生成できることを保証する。

    次のコードは、各ページのヘッダーデータ構造を示しています。

    typedef struct PageHeaderData
    {
        /* XXX LSN is member of *any* block, not only page-organized ones */
        PageXLogRecPtr pd_lsn;      /* LSN: next byte after last byte of xlog
                                     * record for last change to this page */
        uint16      pd_checksum;    /* checksum */
        uint16      pd_flags;       /* flag bits, see below */
        LocationIndex pd_lower;     /* offset to start of free space */
        LocationIndex pd_upper;     /* offset to end of free space */
        LocationIndex pd_special;   /* offset to start of special space */
        uint16      pd_pagesize_version;
        TransactionId pd_prune_xid; /* oldest prunable XID, or zero if none */
        ItemIdData  pd_linp[FLEXIBLE_ARRAY_MEMBER]; /* line pointer array */
    } PageHeaderData;
    説明
    • pd_lsnは、IVがその解読に必要であるため、暗号化されない。

    • pd_flagsは、ページが暗号化されているかどうかを示す0x800 0フラグを追加します。 pd_flagsは暗号化されません。 このアプローチは、平文ページとの互換性を維持し、増分クラスタのためのTDEの導入を可能にする。

    • pd_checksumは暗号化されません。 このようにして、ページチェックサムを暗号文でチェックできます。

    • 暗号化ファイル

      ユーザーデータを含むファイルは暗号化されます。 たとえば、データディレクトリの次のサブディレクトリ内のファイルは暗号化されます。

      • base/

      • global/

      • pg_tblspc/

      • pg_replslot/

      • pg_stat/

      • pg_stat_tmp/

    • 暗号化する場合

      データページごとに整理されるデータは、ページごとに暗号化されます。 ページデータをディスクに書き込む前に、PageSetChecksumCopyやパラメーターが無効の場合はPageSetChecksumInplaceなどのチェックサム関連パラメーターまたは関数を使用して、チェックサムを計算する必要があります。 チェックサムを計算する前に、ページデータを暗号化する必要があります。 これにより、ストレージ内のユーザーデータが暗号化されます。

  • 解読モジュール

    記憶されたページデータは、メモリに読み込まれる前に、チェックサムを用いて検証されなければならない。 検証パラメータが無効になっている場合、検証関数PageIsVerifiedが呼び出されます。 したがって、チェックサム検証後にデータの復号化が行われる限り、メモリ内のデータは復号化される。