2022年5月19日木曜日

APIキーのクリデンシャルにPKCS#1とPKCS#8の両方が使えることを確認する

Oracle CloudでAPIキーを登録する方法として、大きく2つあります。

  1. OCIコンソールでAPIキー・ペアを生成し、秘密キーのダウンロードを実行する。
  2. opensslを実行して、手元でキー・ペアを生成し、公開キーをAPIキーとして登録する。
APIキーの追加ユーザーの詳細リソースより、APIキーを開いて実施します。


APIキーの追加をクリックしてダイアログを開き、APIキー・ペアの生成を選択します。秘密キーのダウンロードをクリックすると、クリデンシャルの作成時に指定する秘密キーが、ファイルとしてダウンロードされます。


ダウンロードされた秘密キーを見ると、ヘッダーとフッターがBEGIN PRIVATE KEYEND PRIVATE KEYであることが確認できます。このファイル・フォーマットはPKCS#8です。
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCUH6zriPt/Oa/1
...
[中略]
....
645WM5ZXhQIEeNU7WFhe9Q==
-----END PRIVATE KEY-----
マニュアルでは、以下のコマンドを実行してAPIキーに使うキー・ペアを生成しています。
openssl genrsa -out ~/.oci/oci_api_key.pem 2048
生成されたファイルを見ると、ヘッダーとフッターがBEGIN RSA PRIVATE KEYEND RSA PRIVATE KEYであることが確認できます。このファイル・フォーマットはPKCS#1です。
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAt2juWKiGzd43+Fc3qRfZE4rmgVfR4fmyvlz1Ep+JqY8wUWzU
...
[中略]
...
ui1D93DenZRMJe5SQO4YzWHZobSr0DCR7cqTcsWmwNdZEOK2I725bA==
-----END RSA PRIVATE KEY-----
どちらの方法で作成した秘密キーでも、問題なくクリデンシャルは作れていました。

これらの秘密キーの情報を使って作成するクリデンシャルとして、DBMS_CLOUD.CREATE_CREDENTIALを使って作成するものと、Oracle APEXのWeb資格証明として作成するものがあります。

結論をからいうと、秘密キーとしてPKCS#1とPKCS#8のどちらのフォーマットでクリデンシャル/Web資格証明を作っても問題ありません。

確認のために、オブジェクト・ストレージにJSONファイルを配置し、それを読み取ってみました。JSONファイルは以下のパスよりアクセスします。

https://objectstorage.us-ashburn-1.oraclecloud.com/n/ネームスペース/b/data/o/f1-races-2022.json

クリデンシャルを与えずにアクセスすると、BucketNotFoundが発生します。

{"code": "BucketNotFound","message": "Either the bucket named 'data' does not exist in the namespace 'ネームスペース' or you are not authorized to access it"}


APEXでのWeb資格証明の作成



APEXでは、ワークスペース・ユーティリティWeb資格証明(または各アプリケーションの共有コンポーネントWeb資格証明)よりクリデンシャルを作成します。

Web資格証明名前MY_DATA_CRED8とし、OCI秘密キーにファイル・フォーマットがPKCS#8のデータを与えます。OCIユーザーIDOCIテナンシIDおよびOCI公開キー・フィンガープリントは、APIキーを作成した際に表示される構成情報に含まれています。


ここで使用したPKCS#8の秘密キーをPKCS#1にフォーマット変換します。PKCS#8のデータをpkcs8.pemに書き込み、opensslの以下のコマンドを実行します。
openssl rsa -in pkcs8.pem -outform PEM -out pkcs1.pem
生成したPKCS#1の秘密キーを使って、PKCS#8のときと同様にWeb資格証明を作成します。名前はMY_DATA_CRED1とします。OCI秘密キー以外は同じ値を設定します。


PKCS#1からPKCS#8を生成する場合は、以下のコマンドを使用します。
openssl pkcs8 -topk8 -nocrypt -in pkcs1.pem -outform PEM -out pkcs8.pem


RESTデータ・ソースの確認



APEXアプリケーションの共有コンポーネントより、RESTデータ・ソースを作成します。


作成済のRESTデータ・ソースが一覧されます。作成をクリックします。


RESTデータ・ソースの作成として最初からを選択し、へ進みます。


RESTデータ・ソース・タイプとして簡易HTTPを選択し、名前F1レース-PKCS#8URLエンドポイントとして、オブジェクト・ストレージ上のJSONファイルへのパスを指定します。

へ進みます。


リモート・サーバーベースURLおよびサービスURLパスは自動的に決まるので、そのまま変更しません。

へ進みます。


ページ区切りタイプとして、ページ区切りなしを選択します。

へ進みます。


認証の設定に移ります。認証が必要ですONに変更し、資格証明として作成済のMY_DATA_CRED8(PKCS#8の秘密キーで作成)を選択します。

検出を実行します。


JSONファイルの内容が表示されます。これで資格証明MY_DATA_CRED8が有効であることが確認できました。

RESTデータ・ソースの作成をクリックして、確認作業は終了です。


同様の手順で、資格証明としてMY_DATA_CRED1を使ったRESTデータ・ソースF1レース-PKCS#1を作成します。

こちらも問題なく作成できます。



APEX_WEB_SERVICE.MAKE_REST_REQUESTの確認



APEX_WEB_SERVICE.MAKE_REST_REQUESTを呼び出す以下のコードを実行し、JSONファイルが取得できるか確認します。p_credential_static_idにWeb資格証明の静的IDを指定します。


SQLワークショップSQLコマンドから実行します。


資格証明のMY_DATA_PKCS8MY_DATA_PKCS1の両方で、JSONファイルが取得できることが確認できます。


OCIのクリデンシャルの作成



DBMS_CLOUD.CREATE_CREDENTIALを呼び出す以下のスクリプトを実行し、Oracle CloudのAPIで使用できるクリデンシャルを作成します。引数のuser_ocidtenancy_ocidfingerprintに与える値は、はAPIキーを作成した際に表示された構成情報に含まれています。


秘密キーがPKCS#8のクリデンシャルMY_DATA_CRED8を作成します。APEXのワークスペース・スキーマに、パッケージDBMS_CLOUDの実行権限が割り当てられている必要があります。


同様の手順で、秘密キーがPKCS#1のクリデンシャルMY_DATA_CRED1を作成します。

作成されたクリデンシャルを確認します。
select credential_name, enabled from user_credentials where credential_name like 'MY_DATA%'


APEXのWeb資格証明とは保存先が異なるため、名前が同じでも実体は異なります。


DBMS_CLOUD.SEND_REQUESTの確認



DBMS_CLOUD.SEND_REQUESTを使って確認します。以下のコードを実行します。APEXのワークスペース・スキーマには、パッケージDBMS_CLOUDに加えて、DBMS_CLOUD_TYPESの実行権限が必要です。




クリデンシャルMY_DATA_CRED8およびMY_DATA_CRED1の両方で、JSONファイルの取得に成功します。


PL/SQL SDKの確認



OCIのオブジェクト・ストレージPL/SQL SDKを使用します。APEXのワークスペース・スキーマに以下の権限が与えらられているのが前提です。
grant execute on dbms_cloud_oci_obs_object_storage_get_object_response_t to apexdev;
grant execute on dbms_cloud_oci_obs_object_storage to apexdev;
確認のために、以下のコードを実行します。




クリデンシャルMY_DATA_CRED8およびMY_DATA_CRED1の両方で、JSONファイルの取得に成功します。

以上で、クリデンシャルの秘密キーのフォーマットが、PKCS#1とPKCS#8のどちらでも問題なく使用できることが確認できました。