この章の内容は、次のとおりです。
関連項目:
|
データの暗号化には多くのメリットがありますが、多くのデメリットもあります。暗号化はすべてのセキュリティ問題を解決するわけではなく、不都合な問題の原因となる場合もあります。次の各項では、格納データの暗号化に関する誤解のいくつかについて説明します。
ほとんどの組織で、データのアクセスを、そのデータを参照する必要があるユーザーのみに制限する必要があります。たとえば、人事管理システムでは、従業員には各自の雇用レコードのみを参照できるように制限し、従業員の上司には直属の部下の雇用レコードを参照できるようにする場合があります。人事部門の担当者が複数の従業員の従業員レコードを参照する必要がある場合もあります。
一般的には、アクセス制御メカニズムを使用して、データを見る必要がある人にデータ・アクセスを制限するセキュリティ・ポリシーに対処できます。Oracle Databaseは、強力で独自に評価されたアクセス制御メカニズムを何年もの間提供してきました。仮想プライベート・データベースにより、アクセス制御を詳細なレベルまで規定できます。
人事部門のレコードは機密情報とみなされるため、セキュリティをより強化するためにこの情報はすべて暗号化する必要があると考えがちです。しかし、暗号化によってきめ細かいアクセス制御を規定できなくなるため、データ・アクセスの妨げとなる場合があります。たとえば、従業員、その上司および人事部門の担当者すべてが、従業員レコードにアクセスする必要がある場合があります。従業員データがすべて暗号化されている場合、この3人は暗号化されていない形式のデータにアクセスできる必要があります。したがって、従業員、上司および人事部門の担当者はデータを復号化するために同じ暗号化鍵を共有する必要があります。このように、アクセス制御の向上という観点では、暗号化によってセキュリティが強化されず、アプリケーションの正しい機能や効率的な機能の妨げとなる場合があります。さらに、システムの複数のユーザー間で暗号化鍵の送信および共有を安全に行うことは難しいという別の問題もあります。
格納データを暗号化するときの基本原則は、暗号化によってアクセス制御が妨げられないようにすることです。たとえば、emp
に対するSELECT
権限を持つユーザーが、基本的には参照できるすべてのデータへの参照を暗号化メカニズムによって制限されないようにする必要があります。また、ユーザーが表のすべての暗号化データを参照する必要がある場合は、ある鍵を使用して表の一部を暗号化し、別の鍵を使用して表の他の部分を暗号化するメリットはほとんどありません。この場合、ユーザーがデータを参照できるように、データを復号化するオーバーヘッドが増加するのみです。アクセス制御が適切に実装されている場合は、暗号化によってデータベース自体の中でセキュリティが強化されることはほとんどありません。データベース内のデータにアクセスする権限を持つユーザーについては、暗号化しても権限は変わりません。したがって、アクセス制御の問題解決に暗号化を使用しないでください。
不正なユーザーがパスワードを推測して上位(データベース管理者)の権限を取得する可能性を懸念して、この脅威から保護するために格納データを暗号化することを考える組織もあります。ただし、この問題の正しい解決策は、データベース管理者アカウントを保護し、その他の権限付きアカウントのデフォルトのパスワードを変更することです。データベースに侵入する最も簡単な方法は、管理者が変更しないままにしている権限付きアカウントのデフォルトのパスワードを使用することです。その一例がSYS
/CHANGE_ON_INSTALL
です。
不正なユーザーがDBA
権限を取得すると、データベースに対して多くの破壊的な行為を実行できますが、暗号化ではそれらの行為の多くからデータベースを保護できません。たとえば、データを破壊または削除する行為、ユーザー・データをファイル・システムにエクスポートし、そのデータを電子メールで自分自身に戻してパスワード・クラッカを実行するなどの行為があります。
データベース管理者は通常すべての権限を所有しているため、データベース管理者がデータベース内のすべてのデータを参照できることについて懸念を持つ組織もあります。そのような組織では、データベース管理者はデータベースを管理するのみで、そのデータベースに含まれるデータを参照できないようにする必要があると考えます。また、1人のユーザーに非常に多くの権限が集中することを懸念し、DBA機能を分割するか、または2人でアクセスするルールを規定する方が望ましいと考える組織もあります。
すべてのデータ(または大量のデータ)を暗号化すると、前述の問題が解決すると考えがちですが、このような不正行為からデータを保護するためのより優れた方法があります。たとえば、Oracle DatabaseではDBA
権限の制限付きの分割がサポートされています。Oracle Databaseでは、SYSDBA
ユーザーとSYSOPER
ユーザーに対するネイティブなサポートが提供されています。SYSDBA
はすべての権限を所有しますが、SYSOPER
は制限付き権限セット(データベースの起動および停止など)を所有します。
さらに、複数のシステム権限を網羅する、より小さなロールを作成することもできます。たとえば、jr_dba
ロールには、すべてのシステム権限を含めるのではなく、準データベース管理者に適切なロールのみ(CREATE TABLE
、CREATE USER
など)を含めます。
Oracle Databaseは、SYS
(またはSYS
権限を持つユーザー)によって実行されたアクションを監査し、オペレーティング・システムの保護位置にその監査証跡を格納できます。このモデルを使用すると、オペレーティング・システムに対してルート権限を持つ別の監査人が、SYS
によって実行されたすべてのアクションを監査できるため、監査人は、すべてのデータベース管理者が実行したアクションに対する責任をデータベース管理者自身に持たせることができます。
データベース管理者を監査する方法の詳細は、「SYS管理ユーザーの監査」を参照してください。
データベース管理者のアクセス権と制御権をOracle Database Vaultを使用して調整することもできます。詳細は、『Oracle Database Vault管理者ガイド』を参照してください。
データベース管理者は信頼される立場にいます。諜報機関のような最も機密性の高いデータを扱う組織においても、通常、データベース管理者機能は分割されません。かわりに、データベース管理者には信頼性が必要なため、厳しく管理されます。定期的な監査によって不適切なアクティビティを明らかにできます。
格納データの暗号化が、データベースの管理を妨げないことが重要です。そうでない場合は、より大きいセキュリティ問題になる可能性があります。たとえば、データを暗号化することでそのデータが破損した場合セキュリティ問題となり、データ自体を解釈できず、修復不可能になる可能性があります。
暗号化を使用すると、データベース管理者(または権限を持つその他のユーザー)がデータベース内のデータを参照する機能を制限できます。ただし、これは、データベース管理者の権限を適切に管理すること、または強力なシステム権限の使用を制御することの代用にはなりません。信頼できないユーザーが重要な権限を持っている場合、そのユーザーが組織に多くの脅威をもたらすこととなり、暗号化されていないクレジット・カード番号を参照されるよりもはるかに深刻な状況に陥る場合もあります。
通常、データの暗号化によってセキュリティが強化されるのであれば、すべてのデータを暗号化することにより、データはすべて保護されると考えますが、これは誤りです。
前述の2つの原則で説明したとおり、暗号化ではアクセス制御の問題に適切に対処できないため、暗号化によって通常のアクセス制御を妨げないことが重要になります。さらに、本番データベース全体を暗号化すると、読取り、更新または削除を行うために、すべてのデータを復号化する必要があります。暗号化は、本来、パフォーマンス集中型の操作であるため、すべてのデータを暗号化するとパフォーマンスに大きい影響を与えます。
可用性はセキュリティの重要な側面です。データの暗号化によって、データを使用できなくなったり、パフォーマンスが低下して可用性に悪影響を与えた場合は、すべてのデータを暗号化することで新たなセキュリティ問題が発生することになります。セキュリティの適切な手続きとして、暗号化鍵を定期的に変更する必要がありますが、このときデータベースにアクセスできなくなります。これも可用性に悪影響を与えます。鍵を変更する場合は、データを復号化して新しい鍵で再度暗号化するまでの間、データベースにアクセスできなくなります。
格納データをオフラインで暗号化することは、メリットもあります。たとえば、組織が半年から1年単位で遠隔地にオフラインでバックアップを格納する場合があります。もちろん、保護の第1段階は、物理的なアクセス制御を確立することによって、データを格納する施設を保護することです。さらに、このデータを格納する前に暗号化すると、メリットがあります。このデータはオンラインでアクセスされないため、パフォーマンスについて考慮する必要はありません。Oracleデータベースにはこの機能が備わっていませんが、暗号化サービスを提供するベンダーがあります。この方法を検討する組織は、バックアップ・データの大規模な暗号化を実施する前に、プロセスを徹底的にテストする必要があります。オフラインで格納する前に、暗号化されたデータを正常に復号化でき、正しく再インポートできることを確認する必要があります。
暗号化によってセキュリティが強化される場合、次の各項で説明するように、いくつかの技術的な課題が伴います。
暗号化データが索引付けされている場合は、特別な問題が発生します。たとえば、ある会社が国民識別番号(米国社会保障番号(SSN)など)を各従業員の従業員番号として使用しているとします。会社は従業員番号を機密性の高いデータと考えているため、employees
表のemployee_number
列のデータを暗号化します。employee_number
列には一意の値が含まれているため、データベース設計者は、パフォーマンスを向上するためにそのデータを索引付けします。
ただし、DBMS_CRYPTO
またはDBMS_OBFUSCATION_TOOLKIT
(または別のメカニズム)を使用して列のデータを暗号化した場合、その列の索引にも暗号化された値が含まれます。列の索引に暗号化された値が含まれている場合、この索引は等価性チェック(たとえば、SELECT * FROM emp WHERE employee_number = '987654321'
)には使用できますが、それ以外の目的には事実上使用できません。索引付けされたデータを暗号化しないでください。
国民識別番号は一意のIDとして使用しないことをお薦めします。かわりに、CREATE SEQUENCE
文を使用して、一意の識別番号を生成してください。国民識別番号を使用しない理由は、次のとおりです。
国民識別番号の乱用に関連するプライバシの問題があること(識別情報の盗難など)
国民識別番号に一部の重複があること(例: 米国社会保障番号)
暗号化されたデータの安全性は、データの暗号化に使用される鍵の安全性に依存します。暗号化鍵は、安全な暗号化鍵生成方法を使用して安全に生成する必要があります。Oracle Databaseは、DBMS_CRYPTO
のRANDOMBYTES
ファンクションを使用した完全な乱数の生成を提供しています。(このファンクションは、以前のDBMS_OBFUSCATION_TOOLKIT
のGetKey
プロシージャによって提供されていた機能にかわるものです。)DBMS_CRYPTO
は、以前にRSA Securityによって認証された安全な乱数ジェネレータ(RNG)をコールします。
注意: DBMS_RANDOM パッケージは使用しないでください。DBMS_RANDOM パッケージは擬似乱数を生成します。「セキュリティのための乱雑性についての推奨事項(RFC-1750)」には、擬似乱数プロセスを使用して機密の数値を生成すると、真のセキュリティを維持できなくなると述べられています。 |
鍵の値を暗号化する場合は、必ず正しいバイト数を指定してください。たとえば、ENCRYPT_AES128
暗号化アルゴリズムの場合は、16バイトの鍵を指定する必要があります。
暗号化鍵がアプリケーションによってデータベースに渡される場合は、暗号化鍵を暗号化する必要があります。暗号化しないと、鍵の転送時に、侵入者が鍵にアクセスできる可能性があります。Oracle Advanced Securityで提供されるようなネットワーク暗号化では、暗号化鍵を含む送信中のデータはすべて、改ざんまたは傍受から保護されます。
暗号化鍵の格納は、暗号化で最も重要で難しい問題の1つです。対称鍵で暗号化されたデータを復元するには、データを復号化しようとする承認済のアプリケーションまたはユーザーが鍵にアクセスできる必要があります。同時に、アクセス権のない暗号化データに不正アクセスしようとするユーザーは、鍵にアクセスできないようにする必要があります。
開発者には次の選択肢があります。
データベース管理者のアクセスから暗号化データを保護しようとする場合、データベースに鍵を格納すると、常に完全なセキュリティを得られない可能性があります。すべての権限を持つデータベース管理者は暗号化鍵を含む表にもアクセスできます。ただし、明確な意図のない詮索好きなユーザーまたはオペレーティング・システム上のデータベース・ファイルを破壊しようとするユーザーに対しては、適切なセキュリティ対策になる可能性があります。
簡単な例として、従業員データを含む表(EMP
)を作成するとします。列の1つに格納されている各従業員の社会保障番号(SSN)を暗号化します。従業員のSSNは、別の列に格納されている鍵を使用して暗号化できます。ただし、表全体に対するSELECT
権限を持っているユーザーは、暗号化鍵を取得し、対応するSSNを復号化できます。
この暗号化スキーマは簡単に侵害できるようにみえますが、多少の取り組みで、非常に強力な不正侵入対策ソリューションを作成できます。たとえば、この方法を使用してSSNを暗号化する前に、employee_number
のデータをさらに変換するテクニックを使用することで、SSNを暗号化できます。これは、employee_number
と従業員の誕生日のXOR
(排他的論理和)演算を使用して値の妥当性を判別するような単純なテクニックの場合もあります。
別の保護として、暗号化を実行するPL/SQLパッケージの本体を(WRAP
ユーティリティを使用して)ラップして、コードを不明瞭化(スクランブル化)する方法もあります。WRAP
ユーティリティは入力SQLファイルを処理し、その中のPL/SQLユニットを不明瞭化します。たとえば、次のコマンドではkeymanage.sql
ファイルを入力として使用しています。
wrap iname=/mydir/keymanage.sql
開発者は次に、ラップされたパッケージに含まれる鍵を使用して、パッケージ内のファンクションにDBMS_OBFUSCATION_TOOLKIT
をコールさせることができます。
Oracle Databaseでは、動的に生成されたPL/SQLコードを不明瞭化できます。DBMS_DDL
パッケージには、動的に生成されたPL/SQLプログラム・ユニットを不明瞭化するために使用できるサブプログラムが2つ含まれています。たとえば、次のブロックでは、DBMS_DDL.CREATE_WRAPPED
プロシージャを使用して、動的に生成されたPL/SQLコードをラップします。
BEGIN
......
SYS.DBMS_DDL.CREATE_WRAPPED(function_returning_PLSQL_code());
......
END;
ラップは解読不可能ではありませんが、侵入者が暗号化鍵にアクセスするのはかなり困難になります。各暗号化データの値ごとに異なる鍵が提供されている場合でも、鍵の値をパッケージ内に埋め込まないでください。かわりに、鍵の管理を実行するパッケージをラップ(つまり、データ変換またはパディング)してください。
関連項目: WRAPコマンドライン・ユーティリティと動的ラップのためのDBMS_DDLサブプログラムの詳細は、
『Oracle Database PL/SQL言語リファレンス』 を参照してください。 |
また、データをラップするかわりに暗号化鍵を別の表に格納し、プロシージャを使用してキー表に対するコールをエンベロープする方法もあります。キー表は、主キーと外部キー関係を使用してデータ表に結合できます。たとえば、employee_number
は、従業員情報と暗号化されたSSNを格納するemployees
表の主キーです。また、employee_number
列は、従業員のSSNの暗号化鍵を格納するssn_keys
表に対する外部キーです。ssn_keys
表に格納された鍵も使用前に(XOR
演算により)変換できるため、鍵自体が暗号化されずに格納されることはありません。プロシージャをラップすると、鍵を使用前に変換する方法を隠すことができます。
この方法のメリットは次のとおりです。
表への直接アクセス権を持つユーザーは、暗号化されていない機密データを参照することも、鍵を取得してデータを復号化することもできません。
復号化されたデータへのアクセスは、暗号化されたデータの選択、キー表からの復号化鍵の取得、およびデータの復号化に使用する鍵の変換を実行するプロシージャを介して制御できます。
データ変換アルゴリズムは、プロシージャをラップし、プロシージャ・コードを不明瞭化することによって、偶発的な傍受から隠されます。
データ表とキー表の両方に対するSELECT
権限があっても、鍵は使用前に変換されるため、この権限を持つユーザーがそのデータを復号化できる保証はありません。
この方法のデメリットは、キー表とデータ表の両方に対するSELECT
権限があり、鍵変換アルゴリズムを導出できるユーザーが、暗号化スキームを解読できることです。
前述の方法は完全ではありませんが、クリアテキストで格納されている機密情報を簡単に取得できないように保護するには十分です。
もう1つの選択肢は、オペレーティング・システムのフラット・ファイルに鍵を格納する方法です。Oracle Databaseでは、PL/SQLからコールアウトを行い、それを使用して暗号化鍵を取得できます。ただし、オペレーティング・システムに鍵を格納し、それに対してコールアウトを行う場合、データはオペレーティング・システムでの保護と同じ程度にのみ保護されます。セキュリティ上の主な懸念が、オペレーティング・システムからデータベースに侵入される可能性があるということである場合、オペレーティング・システムに鍵を格納することは、データベース自体に鍵を格納することより、侵入者にとっては暗号化されたデータを取得しやすくなります。
ユーザーに鍵を提供させる場合は、ユーザー自身がその鍵に責任を持つことを想定しています。ヘルプ・デスクへのコールの40%が、パスワードを忘れたユーザーからのコールであることから、ユーザーが暗号化鍵を管理することのリスクは明らかです。多くの場合、ユーザーは暗号化鍵を忘れるか、鍵を書き留めておくため、セキュリティ上の弱点が生じます。ユーザーが暗号化鍵を忘れたり、会社を退職した場合、データは復元できなくなります。
ユーザーに鍵を提供する、またはユーザーが鍵を管理する場合は、ネットワーク暗号化を使用して、鍵がクリアテキストでクライアントからサーバーに渡されないようにする必要があります。また、鍵アーカイブ・メカニズムを開発する必要があります。これも困難なセキュリティの問題です。鍵アーカイブおよびバックドアは、暗号化によって解決しようとしているセキュリティ上の弱点を生み出すことになります。
慎重なセキュリティの手続きでは、暗号化鍵を定期的に変更するように指示されます。格納データの場合、これを実行するには、データを定期的に暗号解除し、適切な別の鍵を使用して再度暗号化する必要があります。暗号化鍵の変更は、おそらくデータへのアクセスがない間に実行しますが、また別の課題が生まれます。クレジット・カード番号を暗号化するWebベースのアプリケーションでは、暗号化鍵を切り替える間はアプリケーション全体を停止できないため、特に問題になります。
一部のデータ型は、暗号化に手間がかかります。たとえば、Oracle Databaseでは、非常に大規模なオブジェクト(たとえば、数GB)をデータベースに格納するバイナリ・ラージ・オブジェクト(BLOB)をサポートしています。BLOBは、列として内部的に格納するか、または外部ファイルに格納できます。
BLOBデータに対するDBMS_CRYPTO
の使用例は、「BLOBデータの暗号化および復号化プロシージャの例」を参照してください。
DBMS_CRYPTO
パッケージは、論じられてきたセキュリティ問題に取り組むための様々な方法を提供します。(下位互換性を維持するために、DBMS_OBFUSCATION_TOOLKIT
も提供されています。)
暗号化は、複数のセキュリティへの脅威に対処できる理想的なソリューションではありませんが、データベースに格納する前に機密性の高いデータを選択的に暗号化することによって、セキュリティを強化できます。そのようなデータの例は次のとおりです。
クレジット・カード番号
国民識別番号
Oracle Databaseには、格納データの暗号化および復号化のためのPL/SQLパッケージDBMS_CRYPTO
が用意されています。このパッケージは、Advanced Encryption Standard(AES)の暗号化アルゴリズムも含めて、複数の業界標準暗号化およびハッシング・アルゴリズムをサポートしています。AESは、データ暗号化規格(DES)にかわる規格として、National Institute of Standards and Technology(NIST)によって承認されました。
DBMS_CRYPTO
パッケージは、RAW
およびイメージやサウンドなどのラージ・オブジェクト(LOB)を含むOracle Databaseの一般的なデータ型の暗号化および復号化に使用できます。特に、BLOBとCLOBをサポートしています。さらに、様々なデータベース・キャラクタ・セット間でデータを暗号化するためのグローバリゼーション・サポートも提供します。
次の暗号化アルゴリズムがサポートされています。
データ暗号化規格(DES)、Triple-DES(3DES、2-key)
Advanced Encryption Standard(AES)
SHA-1暗号化ハッシュ
SHA-1メッセージ認証コード(MAC)
DBMS_CRYPTO
ではブロック暗号修飾子も提供されています。Public Key Cryptographic Standard(PKCS)#5を含む複数のパディング・オプションおよびCipher Block Chaining(CBC)を含む4つのブロック暗号連鎖モードから選択できます。パディングは8バイトの倍数で実行する必要があります。
注意:
|
表8-1に、DBMS_CRYPTO
パッケージともう1つのPL/SQL暗号化パッケージDBMS_OBFUSCATION_TOOLKIT
との機能の比較を示します。
表8-1 DBMS_CRYPTOとDBMS_OBFUSCATION_TOOLKITとの機能の比較
パッケージ機能 | DBMS_CRYPTO | DBMS_OBFUSCATION_TOOLKIT |
---|---|---|
暗号化アルゴリズム |
DES、3DES、AES、RC4、3DES_2KEY |
DES、3DES |
パディング形式 |
PKCS5、複数ゼロ |
サポートなし |
ブロック暗号連鎖モード |
CBC、CFB、ECB、OFB |
CBC |
暗号化ハッシュ・アルゴリズム |
SHA-1、MD4、MD5 |
MD5 |
鍵ハッシュ(MAC)・アルゴリズム |
HMAC_MD5、HMAC_SH1 |
サポートなし |
暗号化擬似乱数ジェネレータ |
|
|
データベース型 |
|
|
DBMS_CRYPTO
は、使いやすく、新しいシステムと既存システムの両方に対応する広範囲のアルゴリズムをサポートしているため、OBFUSCATION_TOOLKIT
パッケージと置き換えてください。3DES_2KEYおよびMD4は下位互換性を維持するために提供されていますが、3DES、AESまたはSHA-1を使用するとセキュリティをより強化できます。3DES_2KEYおよびMD4の使用はお薦めしません。
DBMS_CRYPTO
パッケージには、比較の際に便利な暗号チェックサム機能(MD5)と、安全な乱数を生成する機能(RANDOMBYTES
関数)が含まれています。安全な乱数生成は暗号化の重要な部分です。予測可能な鍵は簡単に推定される鍵であり、鍵を簡単に推定できることによってデータが簡単に復号化される可能性があります。ほとんどの暗号解読が、総当たり解析(可能性のあるすべての鍵を繰り返す)によってではなく、脆弱な鍵や適切に格納されていない鍵を見つけ出すことによって行われています。
鍵の管理はプログラムによって実行されます。つまり、アプリケーション(またはファンクションのコール側)が、暗号化鍵を提供する必要があります。これは、アプリケーション開発者が鍵を安全に格納し、取得する方法を検討する必要があることを意味します。様々な鍵管理方法の相対的なメリットとデメリットについては、後続の項で説明します。文字列とRAWデータの両方を処理できるDBMS_OBFUSCATION_TOOLKIT
パッケージには、64ビットの鍵を送信する必要があります。DESアルゴリズム自体の有効な鍵の長さは56ビットです。
注意: DBMS_OBFUSCATION_TOOLKIT は、デフォルトでPUBLIC に付与されます。この権限付与を取り消すことをお薦めします。
|
関連項目:
|
この項の内容は、次のとおりです。
次に、データを暗号化するためのPL/SQLプログラム(dbms_crypto.sql
)のサンプルを示します。このサンプル・コードでは、次の処理を実行します。
文字列(VARCHAR2
型)をRAW
データ型に変換した後、DESを使用して暗号化します。
DBMS_OBFUSCATION_TOOLKIT
パッケージのファンクションやパッケージとは異なり、DBMS_CRYPTO
パッケージの暗号化および復号化ファンクションとプロシージャはRAW
データ型にのみ機能するため、このステップが必要となります。
SHA-1アルゴリズムを使用した160ビット・ハッシュの作成方法を示します。
MD5アルゴリズムを使用した鍵依存の一方向ハッシュであるMACの計算方法を示します。
dbms_crypto.sql
プロシージャは次のとおりです。
DECLARE
input_string VARCHAR2(16) := 'tigertigertigert';
raw_input RAW(128) :=
UTL_RAW.CAST_TO_RAW(CONVERT(input_string,'AL32UTF8','US7ASCII'));
key_string VARCHAR2(8) := 'scottsco';
raw_key RAW(128) :=
UTL_RAW.CAST_TO_RAW(CONVERT(key_string,'AL32UTF8','US7ASCII'));
encrypted_raw RAW(2048);
encrypted_string VARCHAR2(2048);
decrypted_raw RAW(2048);
decrypted_string VARCHAR2(2048);
-- Begin testing Encryption:
BEGIN
dbms_output.put_line('> Input String : ' ||
CONVERT(UTL_RAW.CAST_TO_VARCHAR2(raw_input),'US7ASCII','AL32UTF8'));
dbms_output.put_line('> ========= BEGIN TEST Encrypt =========');
encrypted_raw := dbms_crypto.Encrypt(
src => raw_input,
typ => DBMS_CRYPTO.DES_CBC_PKCS5,
key => raw_key);
dbms_output.put_line('> Encrypted hex value : ' ||
rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
decrypted_raw := dbms_crypto.Decrypt(
src => encrypted_raw,
typ => DBMS_CRYPTO.DES_CBC_PKCS5,
key => raw_key);
decrypted_string :=
CONVERT(UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw),'US7ASCII','AL32UTF8');
dbms_output.put_line('> Decrypted string output : ' ||
decrypted_string);
if input_string = decrypted_string THEN
dbms_output.put_line('> String DES Encyption and Decryption successful');
END if;
dbms_output.put_line('');
dbms_output.put_line('> ========= BEGIN TEST Hash =========');
encrypted_raw := dbms_crypto.Hash(
src => raw_input,
typ => DBMS_CRYPTO.HASH_SH1);
dbms_output.put_line('> Hash value of input string : ' ||
rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
dbms_output.put_line('> ========= BEGIN TEST Mac =========');
encrypted_raw := dbms_crypto.Mac(
src => raw_input,
typ => DBMS_CRYPTO.HMAC_MD5,
key => raw_key);
dbms_output.put_line('> Message Authentication Code : ' ||
rawtohex(UTL_RAW.CAST_TO_RAW(encrypted_raw)));
dbms_output.put_line('');
dbms_output.put_line('> End of DBMS_CRYPTO tests ');
END;
/
次のPL/SQLブロックは、Cipher Block ChainingとPKCS #5パディングを使用するAES 256ビット・アルゴリズムを使用して、input_string
という事前定義の変数を暗号化および復号化する方法を示します。
declare input_string VARCHAR2 (200) := 'Secret Message'; output_string VARCHAR2 (200); encrypted_raw RAW (2000); -- stores encrypted binary text decrypted_raw RAW (2000); -- stores decrypted binary text num_key_bytes NUMBER := 256/8; -- key length 256 bits (32 bytes) key_bytes_raw RAW (32); -- stores 256-bit encryption key encryption_type PLS_INTEGER := -- total encryption type DBMS_CRYPTO.ENCRYPT_AES256 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5; begin DBMS_OUTPUT.PUT_LINE ('Original string: ' || input_string); key_bytes_raw := DBMS_CRYPTO.RANDOMBYTES (num_key_bytes); encrypted_raw := DBMS_CRYPTO.ENCRYPT ( src => UTL_I18N.STRING_TO_RAW (input_string, 'AL32UTF8'), typ => encryption_type, key => key_bytes_raw ); -- The encrypted value in the encrypted_raw variable can be used here: decrypted_raw := DBMS_CRYPTO.DECRYPT ( src => encrypted_raw, typ => encryption_type, key => key_bytes_raw ); output_string := UTL_I18N.RAW_TO_CHAR (decrypted_raw, 'AL32UTF8'); DBMS_OUTPUT.PUT_LINE ('Decrypted string: ' || output_string); end;
次に、BLOBデータを暗号化および復号化するためのPL/SQLプログラム(blob_test.sql
)のサンプルを示します。このサンプル・コードは次の操作を実行し、ステップごとに進捗状況(または問題)を出力します。
BLOB列の表を作成します。
RAWの値をその表に挿入します。
RAWデータを暗号化します。
暗号化されたデータを復号化します。
blob_test.sql
プロシージャは次のとおりです。
-- 1. Create a table for BLOB column: create table table_lob (id number, loc blob); -- 2. Insert 3 empty lobs for src/enc/dec: insert into table_lob values (1, EMPTY_BLOB()); insert into table_lob values (2, EMPTY_BLOB()); insert into table_lob values (3, EMPTY_BLOB()); set echo on set serveroutput on declare srcdata RAW(1000); srcblob BLOB; encrypblob BLOB; encrypraw RAW(1000); encrawlen BINARY_INTEGER; decrypblob BLOB; decrypraw RAW(1000); decrawlen BINARY_INTEGER; leng INTEGER; begin -- RAW input data 16 bytes srcdata := hextoraw('6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D'); dbms_output.put_line('---'); dbms_output.put_line('input is ' || srcdata); dbms_output.put_line('---'); -- select empty lob locators for src/enc/dec select loc into srcblob from table_lob where id = 1; select loc into encrypblob from table_lob where id = 2; select loc into decrypblob from table_lob where id = 3; dbms_output.put_line('Created Empty LOBS'); dbms_output.put_line('---'); leng := DBMS_LOB.GETLENGTH(srcblob); IF leng IS NULL THEN dbms_output.put_line('Source BLOB Len NULL '); ELSE dbms_output.put_line('Source BLOB Len ' || leng); END IF; leng := DBMS_LOB.GETLENGTH(encrypblob); IF leng IS NULL THEN dbms_output.put_line('Encrypt BLOB Len NULL '); ELSE dbms_output.put_line('Encrypt BLOB Len ' || leng); END IF; leng := DBMS_LOB.GETLENGTH(decrypblob); IF leng IS NULL THEN dbms_output.put_line('Decrypt BLOB Len NULL '); ELSE dbms_output.put_line('Decrypt BLOB Len ' || leng); END IF; -- 3. Write source raw data into blob: DBMS_LOB.OPEN (srcblob, DBMS_LOB.lob_readwrite); DBMS_LOB.WRITEAPPEND (srcblob, 16, srcdata); DBMS_LOB.CLOSE (srcblob); dbms_output.put_line('Source raw data written to source blob'); dbms_output.put_line('---'); leng := DBMS_LOB.GETLENGTH(srcblob); IF leng IS NULL THEN dbms_output.put_line('source BLOB Len NULL '); ELSE dbms_output.put_line('Source BLOB Len ' || leng); END IF; /* * Procedure Encrypt * Arguments: srcblob -> Source BLOB * encrypblob -> Output BLOB for encrypted data * DBMS_CRYPTO.AES_CBC_PKCS5 -> Algo : AES * Chaining : CBC * Padding : PKCS5 * 256 bit key for AES passed as RAW * -> hextoraw('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F') * IV (Initialization Vector) for AES algo passed as RAW * -> hextoraw('00000000000000000000000000000000') */ DBMS_CRYPTO.Encrypt(encrypblob, srcblob, DBMS_CRYPTO.AES_CBC_PKCS5, hextoraw ('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'), hextoraw('00000000000000000000000000000000')); dbms_output.put_line('Encryption Done'); dbms_output.put_line('---'); leng := DBMS_LOB.GETLENGTH(encrypblob); IF leng IS NULL THEN dbms_output.put_line('Encrypt BLOB Len NULL'); ELSE dbms_output.put_line('Encrypt BLOB Len ' || leng); END IF; -- 4. Read encrypblob to a raw: encrawlen := 999; DBMS_LOB.OPEN (encrypblob, DBMS_LOB.lob_readwrite); DBMS_LOB.READ (encrypblob, encrawlen, 1, encrypraw); DBMS_LOB.CLOSE (encrypblob); dbms_output.put_line('Read encrypt blob to a raw'); dbms_output.put_line('---'); dbms_output.put_line('Encrypted data is (256 bit key) ' || encrypraw); dbms_output.put_line('---'); /* * Procedure Decrypt * Arguments: encrypblob -> Encrypted BLOB to decrypt * decrypblob -> Output BLOB for decrypted data in RAW * DBMS_CRYPTO.AES_CBC_PKCS5 -> Algo : AES * Chaining : CBC * Padding : PKCS5 * 256 bit key for AES passed as RAW (same as used during Encrypt) * -> hextoraw('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F') * IV (Initialization Vector) for AES algo passed as RAW (same as used during Encrypt) * -> hextoraw('00000000000000000000000000000000') */ DBMS_CRYPTO.Decrypt(decrypblob, encrypblob, DBMS_CRYPTO.AES_CBC_PKCS5, hextoraw ('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'), hextoraw('00000000000000000000000000000000')); leng := DBMS_LOB.GETLENGTH(decrypblob); IF leng IS NULL THEN dbms_output.put_line('Decrypt BLOB Len NULL'); ELSE dbms_output.put_line('Decrypt BLOB Len ' || leng); END IF; -- Read decrypblob to a raw decrawlen := 999; DBMS_LOB.OPEN (decrypblob, DBMS_LOB.lob_readwrite); DBMS_LOB.READ (decrypblob, decrawlen, 1, decrypraw); DBMS_LOB.CLOSE (decrypblob); dbms_output.put_line('Decrypted data is (256 bit key) ' || decrypraw); dbms_output.put_line('---'); DBMS_LOB.OPEN (srcblob, DBMS_LOB.lob_readwrite); DBMS_LOB.TRIM (srcblob, 0); DBMS_LOB.CLOSE (srcblob); DBMS_LOB.OPEN (encrypblob, DBMS_LOB.lob_readwrite); DBMS_LOB.TRIM (encrypblob, 0); DBMS_LOB.CLOSE (encrypblob); DBMS_LOB.OPEN (decrypblob, DBMS_LOB.lob_readwrite); DBMS_LOB.TRIM (decrypblob, 0); DBMS_LOB.CLOSE (decrypblob); end; / truncate table table_lob; drop table table_lob;
表8-2に、暗号化データに関する情報にアクセスするために問合せ可能なデータ・ディクショナリ・ビューをリストします。これらのビューの詳細は、『Oracle Databaseリファレンス』を参照してください。
表8-2 暗号化データに関する情報を表示するデータ・ディクショナリ・ビュー
ビュー | 説明 |
---|---|
|
ユーザーがアクセスできるすべての表にあるすべての暗号化列の暗号化アルゴリズム情報が表示されます。 |
|
データベースにあるすべての暗号化列の暗号化アルゴリズム情報が表示されます。 |
|
ユーザー・スキーマのすべての表にあるすべての暗号化列の暗号化アルゴリズム情報が表示されます。 |
|
暗号化された表領域に関する情報が表示されます。 |
|
透過的データ暗号化のウォレットのステータスおよびウォレットの場所に関する情報が表示されます。 |
|
サポートされている暗号化アルゴリズムが表示されます。 |