bea ホーム | 製品 | dev2dev | support | askBEA |
![]() |
![]() |
|
![]() |
e-docs > Tuxedo > Tuxedo のセキュリティ機能 > セキュリティのプログラミング |
Tuxedo のセキュリティ機能
|
セキュリティのプログラミング
以下の節では、BEA Tuxedo ATMI アプリケーションのセキュリティをコーディングする方法について説明します。
セキュリティのプログラミングとは
セキュリティのプログラミングとは、アプリケーション・トランザクション・モニタ・インターフェイス (ATMI) アプリケーション用のセキュリティ・コードを記述する作業です。アプリケーション・プログラマは、プログラムのロジックを表すコードを記述するほか、ATMI を使用して、アプリケーション・コードを BEA Tuxedo トランザクション・モニタにリンクします。ATMI プログラミング・インターフェイスを使用すると、BEA Tuxedo トランザクション・モニタで制御される、アプリケーション・クライアントとアプリケーション・サーバ間の通信を実現できます。ATMI には、C および COBOL 用のインプリメンテーションがあります。
次の図に示すように、アプリケーション・プログラマは、ATMI 関数を使用して、ユーザを認証したり、ユーザによるアクセスを制御したり、公開鍵による暗号化の技術をアプリケーションに組み込むことができます。ただし、図が示すとおり、監査およびリンク・レベルの暗号化を行うための ATMI 関数は、アプリケーション・レベルでは用意されていません。監査は、BEA Tuxedo のシステム・レベルで実行されます。また、リンク・レベルの暗号化は、アプリケーション管理者側で設定します。
図 3-1 BEA Tuxedo のセキュリティのプログラミング
セキュリティを備えた ATMI アプリケーションのプログラミング
BEA Tuxedo システムには、セキュリティのニーズに応じた、さまざまな ATMI 関数が用意されています。
関連項目
プログラミング環境の設定
セキュリティ・コードを記述するため、アプリケーション・プログラマには次の権限が必要です。
必要なライブラリおよびコマンドにアクセスするには、環境内で、TUXCONFIG、TUXDIR、APPDIR、およびその他の環境変数を設定する必要があります。詳細については、『BEA Tuxedo アプリケーション実行時の管理』の1-3 ページの「環境変数の設定」を参照してください。
アプリケーション管理者は、ディレクトリおよびファイルのパーミッションを設定します。必要なパーミッションを取得するには、担当の管理者に問い合わせてください。
関連項目
ATMI アプリケーションにクライアント・プログラムを参加させるためのセキュリティ・コードの記述方法
クライアント・プログラムには、アプリケーションまたはコンピュータ以外からのデータを収集したり、データをメッセージに組み込んだり、処理対象のメッセージをサーバに転送する、という役割があります。ユーザは、現金自動預入支払機 (ATM)、データ入力端末、およびグラフィックス用デバイスなどを使用することにより、クライアント・プログラムを利用します。
デフォルトの認証および認可では、5 つのセキュリティ・レベルのうち、いずれかをアプリケーションに設定できます。最も低いセキュリティ・レベルでは、認証は行われません。最も高いセキュリティ・レベルでは、アクセス制御リストの機能により、サービスを実行し、イベントをポストし、アプリケーション・キューのメッセージをキューに登録 (または登録解除) するユーザが決定されます。ATMI アプリケーションに対するセキュリティ・レベルの設定は、アプリケーション管理者の役割です。
クライアント・プログラムを ATMI アプリケーションに参加させるため、アプリケーション・プログラマは、次の 2 つのタスクを実行する必要があります。
次の擬似コードは、基本的なクライアント・プログラムの動作を示しています。セキュリティ関連の文は太字で示します。
コード リスト3-1 クライアントの擬似コード
main()
{
tpchkauth() を呼び出してアプリケーションのセキュリティ・レベルをチェック
usrname、cltname を取得
アプリケーション・パスワードの入力を要求
ユーザ固有のパスワードの入力を要求
TPINIT バッファを割り当て
最初のクライアント ID を TPINIT バッファに格納
tpinit() を呼び出してアプリケーションのクライアントとして登録
バッファを割り当て
do while true {
ユーザ入力データをバッファに格納
サービス要求を送信
応答を受信
応答をユーザに渡す }
アプリケーションを終了
}
上のリスト内の大部分の文は、C または COBOL の ATMI 関数によってインプリメントされます。ただし、ここでは C 言語のインプリメンテーションだけを示しています。
C 言語で記述されたクライアント・プログラムは、tpinit(3c) を使用して、ATMI アプリケーションに設定されたセキュリティ・レベルに準拠し、アプリケーションに参加します。tpinit() の引数は、TPINIT バッファに対するポインタです。COBOL アプリケーションの場合、クライアント・プログラムは TPINITIALIZE(3cbl) を呼び出し、引数として TPINFDEF-REC レコードに対するポインタを取ります。
関連項目
セキュリティ・データの取得
BEA Tuxedo システムには、さまざまなアプリケーションに対応できるように記述された一般的なクライアント・プログラム用の ATMI 関数が用意されています。クライアントは、この ATMI 関数を使用して、参加先の ATMI アプリケーションに必要なセキュリティ・レベルを決定できます。この ATMI 関数は、tpchkauth(3c) (C) または TPCHKAUTH(3cbl) (COBOL) であり、デフォルトの認証および認可を使用する ATMI アプリケーションで実行されます。tpchkauth() 関数および TPCHKAUTH() 関数は、カスタマイズした認証または認可を使用する ATMI アプリケーションでも使用できますが、使用方法は、カスタマイズしたセキュリティ機能がどのようにインプリメントされているかに応じて異なります。ここでは、主にデフォルトの認証および認可の場合について説明します。
C を使用するアプリケーション・プログラマは、tpchkauth() を使用してアプリケーションのセキュリティ・レベルをチェックしてから、tpinit(3c) を呼び出します。これで、クライアント・プログラムは、tpinit() 呼び出しに必要な ATMI アプリケーション・パスワードとユーザ認証データの入力を要求できます。tpchkauth() は引数なしで呼び出されます。
COBOL を使用するアプリケーション・プログラマは、同じ目的で TPCHKAUTH() を使用してから、TPINITIALIZE(3cbl) を呼び出します。TPCHKAUTH(3cbl) と TPINITIALIZE(3cbl) の構文および機能は、tpchkauth(3c) と tpinit(3c) の場合と同じです。
tpchkauth() 関数 (TPCHKAUTH() ルーチン) を呼び出すと、次のいずれかの値が返されます。
関連項目
ATMI アプリケーションへの参加
セキュリティが設定された ATMI アプリケーションでは、TPINIT バッファ (C の場合) または TPINFDEF-REC レコード (COBOL の場合) を使用して、BEA Tuxedo システムにセキュリティ情報を渡す必要があります。TPINIT バッファは、特殊な型付きバッファであり、クライアントが ATMI アプリケーションに参加しようとするときに、クライアントの ID および認証情報をシステムに渡すためにクライアント・プログラムで使用されます。COBOL の場合は、TPINFDEF-REC レコードが使用されます。
TPINIT は atmi.h ヘッダ・ファイルで定義され、TPINFDEF-REC は COBOL の COPY ファイルで定義されます。次の表は、それぞれの構造体を示しています。
次の表では、TPINIT バッファおよび TPINFDEF-REC レコードのフィールドを示します。
クライアント・プログラムは、tpalloc(3c) を呼び出して TPINIT バッファを割り当てます。次は、8 バイトのアプリケーション固有のデータを tpinit() に渡す準備を行い、クライアントが ATMI アプリケーションに参加できるようにするサンプル・コードです。
コード リスト3-2 TPINIT バッファを割り当てて ATMI アプリケーションに参加する
.
.
.
TPINIT *tpinfo;
.
.
.
if ((tpinfo = (TPINIT *)tpalloc("TPINIT",(char *)NULL,
TPINITNEED(8))) == (TPINIT *)NULL){
Error Routine
}
.
.
.
tpinit(tpinfo) /* ATMI アプリケーションへの参加 */
.
.
.
ワークステーション・クライアントが tpinit() 関数または TPINITIALIZE() ルーチンを呼び出して ATMI アプリケーションに参加すると、次の主なイベントが発生します。
ネイティブ・クライアントが tpinit() 関数または TPINITIALIZE() ルーチンを呼び出して ATMI アプリケーションに参加すると、認証だけが行われます。基本的に、ネイティブ・クライアントは、自分自身を認証します。
クライアントのセキュリティ・データの転送
次の図は、ワークステーション・クライアントの TPINIT バッファからデータを転送する様子を示します。TPINFDEF-REC レコードからデータを転送する場合にもこの図が当てはまります。
図 3-2 ワークステーション・クライアントの TPINIT バッファからデータを転送する
注記 上の図に示す認可手順は、ネイティブ・クライアントが ATMI アプリケーションに参加しようとする場合も基本的に同じです。ただし、ネットワーク・リンクや WSH は無関係です。ネイティブ・クライアントは、自分自身を認証するためです。 上の図では、デフォルトの認証を使用するか、またはカスタマイズした認証を使用するかにより、BEA Tuxedo システムに送信される情報が異なる点に注意してください。デフォルトの認証の場合、cltname、grpname、および flags の各フィールドの値が、プラグイン・インターフェイス以外の方法で、ワークステーション・クライアントのデフォルトの認証プラグインに送信されます。一方、カスタマイズした認証の場合、クライアント・プログラムの作成者は、これらの値のほか、data フィールドで選択した可変長の別の値を組み込むこともできます。 デフォルトの認証を使用する場合、ワークステーション・クライアントの認証プラグインでは、passwd/ PASSWD フィールドが使用され、ネットワーク経由で転送される情報が暗号化されます。このとき、暗号化アルゴリズムとして、56 ビットの DES (Data Encryption Standard) が使用されます。ターゲットの WSH にある認証プラグインでは、TUXCONFIG ファイルに格納されているアプリケーション・パスワードを使用して、この情報を復号化します。ネイティブ・クライアントの場合は、単に、passwd/ PASSWD フィールドの値と、TUXCONFIG ファイルに格納されているアプリケーション・パスワードが比較されます。 注記 ワークステーション・クライアントでは、passwd/ PASSWD フィールドの値が、認証プラグイン・インターフェイス以外の方法で、認証プラグインに送信されます。WSH では、TUXCONFIG ファイルに格納されたアプリケーション・パスワードが、アプリケーションの起動時に、認証プラグイン・インターフェイスによって認証プラグインに送信されます。 ワークステーション・クライアントの認証に成功すると、tpinit() 関数は、最後の処理として、usrname、cltname、および flags の 3 つのフィールド値を含む別のバッファを WSH に送信し、認証済みのワークステーション・クライアントに関するこれらの情報が確実に伝わるようにします。TPINITIALIZE() ルーチンの場合も、最後の処理として、同様の情報を含む別のバッファを送信します。カスタマイズした認証プラグインでは、認証手順でこれらの情報が WSH に送信されない場合がありますが、WSH 側ではレポートを作成するとき、つまり tmadmin(1) printclient (pclt) コマンドを呼び出すときにこれらの情報を必要とします。 ワークステーションまたはネイティブ・クライアントは、セキュリティ・チェックにパスすると、サービス要求を発行したり、応答を受信することができます。 ATMI アプリケーションに参加する前のサービス要求の呼び出し ターゲットの ATMI アプリケーションの SECURITY が NONE に設定されているか、または何も設定されていない場合に、クライアントが、tpinit() または TPINITIALIZE() を呼び出す前にサービス要求 (または ATMI 関数) を呼び出すと、BEA Tuxedo システムは、NULL パラメータで tpinit() または TPINITIALIZE() を自動的に呼び出します。この操作により、次のような結果になります。
ターゲットの ATMI アプリケーションの SECURITY が APP_PW、USER_AUTH、ACL、または MANDATORY_ACL に設定されている場合に、クライアントが、tpinit() または TPINITIALIZE() を呼び出す前にサービス要求 (または ATMI 関数) を呼び出すと、そのサービス要求は拒否されます。
関連項目
データの完全性と機密性を保護するためのセキュリティ・コードの記述方法
公開鍵によるセキュリティは、エンド・ツー・エンドのデジタル署名およびデータの暗号化で構成されています。これらの 2 つの機能は、BEA Tuxedo の ATMI 関数で実現できます。インターネット上でアプリケーションを使用する場合は、公開鍵でセキュリティ保護された ATMI アプリケーションの方が、保護されていないアプリケーションより安全です。
エンド・ツー・エンドのデジタル署名とデータの暗号化は、メッセージ・ベースのデジタル署名およびメッセージ・ベースの暗号化の機能によって実現できます。これらの機能は、PKCS-7 標準に基づいています。PKCS-7 は、RSA Laboratories が主要な通信会社の協力のもとに開発した、PKCS (Public-Key Cryptography Standards) という規格の 1 つです。
メッセージ・ベースのデジタル署名では、送信者の ID を特定のメッセージ・バッファと結び付けることにより、データの完全性を保ち、送信者がメッセージを送信した事実を否認できないようにします。メッセージ・ベースの暗号化では、指定した受信者だけがメッセージを復号化できるため、メッセージの機密性が保たれます。
デジタル署名および暗号化は、ATMI のメッセージ・バッファ単位で行われます。したがって、これらの機能は、既存の ATMI のプログラミング・インターフェイスおよび通信パラダイムと互換性があります。メッセージ・バッファは、署名することも暗号化することもできます。メッセージ・バッファに関連するデジタル署名の数と暗号化エンベロープの数の間に、関係を成立させる必要はありません。
注記 各暗号化エンベロープには、メッセージの受信者を識別し、受信者がメッセージを復号化するために必要な情報が含まれています。
公開鍵によるセキュリティの ATMI インターフェイス
公開鍵によるセキュリティの ATMI は、次の処理を行う関数群です。
公開鍵によるセキュリティの ATMI インターフェイスには、C および COBOL の 2 つのインプリメンテーションがあります。ただし、BEA Tuxedo の COBOL 言語バインディングでは、メッセージ・バッファがサポートされません。したがって、個別のバッファに対する明示的な署名、暗号化、およびクエリ操作は、COBOL のアプリケーションでは使用できません。一方、鍵管理のインターフェイスでは、COBOL 言語バインディングがサポートされているため、AUTOSIGN モードで署名を生成したり、AUTOENCRYPT モードで暗号化エンベロープを生成できます。署名の自動検証機能または自動暗号化機能に関するすべての操作は、COBOL のクライアント・プロセスおよびサーバ・プロセスに適用できます。
注記 COBOL の TPKEYDEF レコードは、メッセージ・ベースのデジタル署名と暗号化操作を実行するための公開鍵と秘密鍵の管理に使用されます。TPKEYDEF レコードの詳細については、『BEA Tuxedo COBOL リファレンス』の紹介部分にある「COBOL 言語 ATMI の戻り値とその他の定義」を参照してください。
次の表は、公開鍵によるセキュリティの ATMI をまとめたものです。各関数については、『BEA Tuxedo C リファレンス』および『BEA Tuxedo COBOL リファレンス』も参照してください。
公開鍵のセキュリティで推奨されている事項について
関連項目
署名付きメッセージの送信と受信
メッセージ・ベースのデジタル署名では、エンド・ツー・エンドの認証が行われ、メッセージの完全性が保たれます。この機能のしくみについては、ATMI PKCS-7 のエンド・ツー・エンドのデジタル署名の図を参照してください。
BEA Tuxedo のメッセージ・バッファにデジタル署名を追加するには、送信側のプロセスまたはユーザがメッセージ・バッファに署名します。この署名には、メッセージ・バッファの内容から得た、暗号法的に安全なチェックサムと、署名者のローカル・クロックに基づいたタイムスタンプが含まれています。
このメッセージ・バッファに対するアクセス権がある場合は、署名者の署名が本物であるかどうか、メッセージ・バッファの内容が変更されていないかどうか、およびタイムスタンプが検証者のローカル・クロックで受け付ける時刻の範囲内かどうかを検証できます。さらに、時間に依存しない、サード・パーティによる検証を行うと、メッセージの非否認性を保証できます。つまり、送信側のプロセスまたはユーザは、メッセージを送信した事実を否認したり、メッセージが改ざんされたと主張することはできません。
署名付きメッセージを送信するためのコードの作成
次のフローチャートでは、署名付きメッセージを送信するコードを記述する手順を示します。
図 3-3 署名付きメッセージの送信手順
これらの手順およびメッセージ・バッファが署名されるしくみについては、以下の節を参照してください。 ステップ 1:デジタル署名用のキー・ハンドルをオープンする まず、tpkey_open(3c) 関数または TPKEYOPEN(3cbl) ルーチンを呼び出して、送信側のプロセスが、署名者の秘密鍵および関連するデジタル証明書を使用できるようにします。秘密鍵は厳しくセキュリティ保護されているため、秘密鍵を所有することは、署名者の ID を所有することと同等の意味があります。 署名者の秘密鍵にアクセスするため、送信側のプロセスは、署名者として動作する権限があることを証明する必要があります。証明の条件は、公開鍵のプラグイン・インターフェイスのインプリメンテーションによって異なります。デフォルトの公開鍵のインプリメンテーションでは、呼び出しプロセス側が秘密のパスワードを入力する必要があります。 送信側のプロセスが tpkey_open() を呼び出してキー・ハンドルをオープンするとき、TPKEY_SIGNATURE フラグまたは TPKEY_AUTOSIGN フラグを指定して、そのキー・ハンドルがメッセージ・バッファのデジタル署名に使用されることを示します。通常、クライアントは tpinit() を呼び出した後でこの呼び出しを行い、サーバは tpsvrinit() を呼び出して初期化を行うときにこの呼び出しを行います。 TPKEY_AUTOSIGN フラグを使用してキー・ハンドルをオープンすると、署名の自動生成が可能になります。以降、送信側のプロセスは、メッセージ・バッファが送信されるたびに、メッセージ・バッファに自動的に署名します。TPKEY_AUTOSIGN フラグを使用すると、次の 3 つの利点があります。
次のコード例では、署名者のキー・ハンドルをオープンする方法を示します。TPKEY は、atmi.h ヘッダ・ファイルで定義される特殊なデータ型です。
コード リスト3-3 署名者のキー・ハンドルをオープンする例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY sdo_key;
char *sdo_location;
.
.
.
if (tpkey_open(&sdo_key, “sdo”, sdo_location,
NULL, 0, TPKEY_SIGNATURE) == -1) {
(void) fprintf(stderr, “tpkey_open sdo failed
tperrno=%d(%s)¥n”, tperrno, tpstrerror(tperrno));
exit(1);
}
.
.
.
}
ステップ 2: (オプション)キー・ハンドルの情報を取得する
署名者のキー・ハンドルの情報を取得して、キーの有効性を確認することができます。そのためには、tpkey_getinfo(3c) 関数または TPKEYGETINFO(3cbl) ルーチンを呼び出します。返される情報の中には、暗号サービス・プロバイダに固有の情報も含まれていますが、主要な属性は、すべてのプロバイダで共通です。
デフォルトの公開鍵のインプリメンテーションでは、メッセージ・バッファの署名を計算するための次の署名モードがサポートされています。
メッセージ・ダイジェスト・アルゴリズムは DIGEST_ALG のキー属性によって制御され、公開鍵署名は SIGNATURE_ALG のキー属性によって制御されます。サポートされている公開鍵のサイズは 512 〜 2048 ビットであり、安全性とパフォーマンスを実現するためには十分な範囲です。公開鍵のサイズは、SIGNATURE_BITS キー属性によって制御されます。
デフォルトの公開鍵のインプリメンテーションでは、上記のアルゴリズムおよびキー・サイズの範囲で作成されたデジタル証明書の署名だけが認識されます。
次のコード例では、署名者のキー・ハンドルに関する情報を取得する方法を示します。
コード リスト3-4 署名者のキー・ハンドルに関する情報を取得する例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY sdo_key;
char principal_name[PNAME_LEN];
long pname_len = PNAME_LEN;
.
.
.
if (tpkey_getinfo(sdo_key, “PRINCIPAL”,
principal_name, &pname_len, 0) == -1) {
(void) fprintf(stdout, “Unable to get information
about principal: %d(%s)¥n”,
tperrno, tpstrerror(tperrno));
.
.
.
exit(1);
}
.
.
.
}
ステップ 3: (オプション)キー・ハンドルの情報を変更する
署名者のキー・ハンドルに関連付けられたオプション属性を設定するには、tpkey_setinfo(3c) 関数または TPKEYSETINFO(3cbl) ルーチンを呼び出します。キー・ハンドル属性は、暗号サービス・プロバイダによって異なります。
次のコード例では、署名者のキー・ハンドルに関連付けられた情報を変更する方法を示します。
コード リスト3-5 署名者のキー・ハンドルに関連付けられた情報を変更する例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY sdo_key;
static const unsigned char sha1_objid[] = {
0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a
};
.
.
.
if (tpkey_setinfo(sdo_key, “DIGEST_ALG”, (void *) sha1_objid,
sizeof(sha1_objid), 0) == -1) {
(void) fprintf(stderr, “tpkey_setinfo failed
tperrno=%d(%s)¥n”,
tperrno, tpstrerror(tperrno));
return(1);
}
.
.
.
}
ステップ 4:バッファを割り当ててメッセージを指定する
型付きメッセージ・バッファを割り当てるには、tpalloc(3c) 関数を呼び出します。続いて、バッファにメッセージを指定します。
ステップ 5:デジタル署名を添付するバッファにマークを付ける
メッセージ・バッファにデジタル署名のマークを付ける (登録する) には、tpsign(3c) 関数を呼び出します。この関数を呼び出すと、署名者のキー・ハンドルのコピーがメッセージ・バッファに添付されます。TPKEY_AUTOSIGN フラグを指定してキーをオープンすると、tpsign() を明示的に呼び出さなくても、デジタル署名を添付するメッセージには自動的にマークが付きます。署名パラメータは保存され、後で使用するためにバッファに関連付けられます。
注記 COBOL のアプリケーションでは、AUTOSIGN 設定のメンバを使用してデジタル署名を作成します。 See TPKEYOPEN(3cbl).
次のコード例は、デジタル署名を添付するメッセージ・バッファにマークをつける方法を示しています。
コード リスト3-6 デジタル署名を添付するメッセージ・バッファにマークを付ける例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY sdo_key;
char *sendbuf, *rcvbuf;
.
.
.
if (tpsign(sendbuf, sdo_key, 0) == -1) {
(void) fprintf(stderr, “tpsign failed tperrno=%d(%s)¥n”,
tperrno, tpstrerror(tperrno));
tpfree(rcvbuf);
tpfree(sendbuf);
tpterm();
(void) tpkey_close(sdo_key, 0);
exit(1);
}
.
.
.
}
ステップ 6:メッセージを送信する
メッセージ・バッファにデジタル署名のマークを付けた後、以下のいずれかの C 関数または COBOL ルーチンを使用して、メッセージ・バッファを送信します。
ステップ 7:署名者のキー・ハンドルをクローズする
tpkey_close(3c) 関数または TPKEYCLOSE(3cbl) ルーチンを呼び出して、署名者のキー・ハンドルとそれに関連付けられたすべてのリソースを解放します。
デジタル署名の生成方法
デジタル署名の添付は、メッセージ・バッファが送信される直前に、公開鍵ソフトウェアによって行われます。デジタル署名されたバッファが複数回送信される場合は、送信のたびに新しい署名が生成されます。したがって、デジタル署名を行うメッセージ・バッファにマークを付けた後で、そのメッセージ・バッファを変更することができます。
公開鍵ソフトウェアは、次の 3 段階の手順でデジタル署名を生成します。
digest[ ] という表記は、メッセージ・ダイジェスト・アルゴリズム (この場合は MD5 または SHA-1) を使用して [ ] 内のハッシュ値が計算されることを示します。{ }key という表記は、key を使用して {} 内が暗号化または復号化されることを示します。この場合、計算されたハッシュ値は、署名者の秘密鍵を使用して暗号化されます。
署名のタイムスタンプ
デジタル署名には、ローカル・システムのクロックに基づいたタイムスタンプが組み込まれます。このようなタイムスタンプを組み込むことにより、受信者が署名を検証するときに、タイムスタンプ値の改ざんが検出されます。さらに、デジタル署名付きメッセージが宛先にルーティングされるとき、そのメッセージにはタイムスタンプのコピーが添付されます。
タイムスタンプは、秒単位まで表記されます。また、タイムスタンプは、PKCS-9 の SigningTime 形式で表記されます。
複数の署名について
1 つのメッセージ・バッファには、複数の署名を関連付けることができます。つまり、1 つのメッセージ・バッファに対して、任意の数の署名者が同時に署名できます。署名できるのは、ユーザまたはプロセスです。各署名者は、自分の秘密鍵を使用してメッセージ・バッファに署名します。
署名が異なる場合は、別のメッセージ・ダイジェスト・アルゴリズムまたはデジタル署名アルゴリズムを使用している可能性があります。同じメッセージ・ダイジェストおよびデジタル署名アルゴリズムを使用した署名が 2 つある場合、ハッシュ値はどちらか 1 つだけに対してだけ計算されます。
署名付きメッセージの内容
デジタル署名付きのメッセージ・バッファは、SignedData というメッセージ・タイプのバージョン 1 として、PKCS-7 形式で表現されます。BEA Tuxedo システムで使用されるメッセージ・タイプ SignedData は、次の項目で構成されます。
次の図に示すように、メッセージの内容は、SignedData というメッセージ・タイプによって包含されています。
図 3-4 SignedData メッセージ・タイプ
署名付きメッセージの受信方法 署名付きメッセージ・バッファを受信するための ATMI アプリケーション・コードは必要ありません。公開鍵ソフトウェアは、添付されたデジタル署名を自動的に検証し、そのメッセージを受信側のプロセスに渡します。 受信側のプロセスの代わりに動作する公開鍵ソフトウェアは、署名付きメッセージ・バッファを受信すると、次のタスクを実行します。
注記 添付されたデジタル署名をどれも検証できない場合、受信側のプロセスは、メッセージ・バッファを受け取りません。さらに、受信側のプロセスは、メッセージ・バッファをまったく認識しません。
デジタル署名を検証する
公開鍵ソフトウェアは、クライアント・プロセス、サーバ・プロセス、またはメッセージ・バッファの内容を読み取るシステム・プロセスに署名付きメッセージ・バッファがあると、メッセージに添付されたデジタル署名を自動的に検証します。ただし、パイプ役として機能するシステム・プロセス (メッセージの内容は読み取らない) の場合、メッセージに添付されたデジタル署名は検証されません。たとえば、ブリッジおよびワークステーション・ハンドラ (WSH) は、パイプ役として機能するシステム・プロセスの例です。
署名に記録されたタイムスタンプは、非同期のクロックに基づいているため、特に、PC またはパーソナル・コンピュータで署名が行われた場合は、完全に信頼できません。ただし、遠い過去または将来を示すタイムスタンプが記録された要求を、サーバ側で拒否することができます。タイムスタンプに基づいて要求を拒否する機能を使用すると、リプレイ攻撃から保護することができます。
入力バッファの署名を検証および送信する
メッセージ・バッファが入力パラメータとして ATMI 関数 (tpacall() など) に渡された場合、公開鍵ソフトウェアは、メッセージにあらかじめ添付された署名を検証してから、メッセージを転送します。この動作によって、複数のプロセスからの署名を付けた情報を、安全かつ確実に転送することができます。
サーバ側で、受信したメッセージ・バッファを変更して転送すると、元の署名は無効になります。この場合、公開鍵ソフトウェアは、無効な署名を検出して破棄します。このプロセスの例については、入力バッファの暗号化エンベロープを破棄するを参照してください。
出力バッファの署名を置換する
メッセージ・バッファが出力パラメータとして ATMI 関数 (tpgetrply() など) に渡された場合、公開鍵ソフトウェアは、このバッファに関連付けられた署名の情報を削除します。削除する情報には、保留中の署名 (メッセージ・バッファに登録された署名)、およびバッファを前回使用したユーザの署名が含まれます。
この操作が正常に終了すると、新しい署名の情報が新しいバッファの内容に関連付けられる場合があります。
関連項目
暗号化されたメッセージの送信と受信
メッセージ・ベースの暗号化では、エンド・ツー・エンドでデータの機密性が保たれます。この機能のしくみについては、ATMI PKCS-7 のエンド・ツー・エンドの暗号化の図を参照してください。
メッセージは、送信側のプロセスを離れる直前に暗号化され、その状態は受信側のプロセスで受信されるまで保持されます。メッセージは、オペレーティング・システムのメッセージ・キュー、システム・プロセス、ディスク・ベース・キューなどの中継ポイントのほか、サーバ間のネットワーク・リンクで転送される間もオペークです。
暗号化されたメッセージを送信するためのコードの作成
次のフローチャートでは、暗号化されたメッセージを送信するコードを記述する手順を示します。
図 3-5 暗号化されたメッセージの送信手順
これらの手順およびメッセージ・バッファが暗号化されるしくみについては、以下の節を参照してください。 ステップ 1:暗号化用のキー・ハンドルをオープンする まず、tpkey_open(3c) 関数または TPKEYOPEN(3cbl) ルーチンを呼び出して、送信側のプロセスが、ターゲット受信者のデジタル証明書を使用できるようにします。ターゲット受信者とは、クライアント、サービス、サーバ・グループ、ゲートウェイ・グループ、サーバ・マシン、または複数のサーバを含むドメイン全体のことです。 送信側のプロセスが tpkey_open() を呼び出してキー・ハンドルをオープンするとき、TPKEY_ENCRYPT フラグまたは TPKEY_AUTOENCRYPT フラグを指定して、そのキー・ハンドルがメッセージ・バッファの暗号化に使用されることを示します。通常、クライアントは tpinit() を呼び出した後でこの呼び出しを行い、サーバは tpsvrinit() を呼び出して初期化を行うときにこの呼び出しを行います。 TPKEY_AUTOENCRYPT フラグを使用してキー・ハンドルをオープンすると、暗号化の自動処理が可能になります。以降、送信側のプロセスは、メッセージ・バッファが送信されるたびに、メッセージ・バッファを自動的に暗号化します。TPKEY_AUTOENCRYPT フラグを使用すると、次の 3 つの利点があります。
次のコード例では、暗号化キー・ハンドルをオープンする方法を示します。TPKEY は、atmi.h ヘッダ・ファイルで定義される特殊なデータ型です。
コード リスト3-7 暗号化キー・ハンドルをオープンする例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY tu_key;
.
.
.
if (tpkey_open(&tu_key, “TOUPPER”, NULL,
NULL, 0, TPKEY_ENCRYPT) == -1) {
(void) fprintf(stderr, “tpkey_open tu failed
tperrno=%d(%s)¥n”, tperrno, tpstrerror(tperrno));
exit(1);
}
.
.
.
}
ステップ 2: (オプション)キー・ハンドルの情報を取得する
暗号化キー・ハンドルの情報を取得して、キーの有効性を確認することができます。そのためには、tpkey_getinfo(3c) 関数または TPKEYGETINFO(3cbl) ルーチンを呼び出します。返される情報の中には、暗号サービス・プロバイダに固有の情報も含まれていますが、主要な属性は、すべてのプロバイダで共通です。
デフォルトの公開鍵のインプリメンテーションでは、バルク・データを暗号化するための 3 つのアルゴリズムがサポートされています。
暗号化のレベルは、ENCRYPT_BITS のキー属性によって制御され、アルゴリズムは ENCRYPT_ALG のキー属性によって制御されます。ENCRYPT_ALG で固定キー長によるアルゴリズムが設定されると、ENCRYPT_BITS の値が自動的に調整されます。
次のコード例では、暗号化キー・ハンドルに関する情報を取得する方法を示します。
コード リスト3-8 暗号化キー・ハンドルに関する情報を取得する例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY tu_key;
char principal_name[PNAME_LEN];
long pname_len = PNAME_LEN;
.
.
.
if (tpkey_getinfo(tu_key, “PRINCIPAL”,
principal_name, &pname_len, 0) == -1) {
(void) fprintf(stdout, “Unable to get information
about principal: %d(%s)¥n”,
tperrno, tpstrerror(tperrno));
.
.
.
exit(1);
}
.
.
.
}
ステップ 3: (オプション)キー・ハンドルの情報を変更する
暗号化キー・ハンドルに関連付けられたオプション属性を設定するには、tpkey_setinfo(3c) 関数または TPKEYSETINFO(3cbl) ルーチンを呼び出します。キー・ハンドル属性は、暗号サービス・プロバイダによって異なります。
次のコード例では、暗号化キー・ハンドルに関連付けられた情報を変更する方法を示します。
コード リスト3-9 暗号化キー・ハンドルに関連付けられた情報を変更する例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY tu_key;
static const unsigned char rc2_objid[] = {
0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02
};
.
.
.
if (tpkey_setinfo(tu_key, “ENCRYPT_ALG”, (void *) rc2_objid,
sizeof(rc2_objid), 0) == -1) {
(void) fprintf(stderr, “tpkey_setinfo failed
tperrno=%d(%s)¥n”,
tperrno, tpstrerror(tperrno));
return(1);
}
.
.
.
}
ステップ 4:バッファを割り当ててメッセージを指定する
型付きメッセージ・バッファを割り当てるには、tpalloc(3c) 関数を呼び出します。続いて、バッファにメッセージを指定します。
ステップ 5:暗号化するバッファにマークを付ける
メッセージ・バッファに暗号化のマークを付ける (登録する) には、tpseal(3c) 関数を呼び出します。この関数を呼び出すと、暗号化キー・ハンドルのコピーがメッセージ・バッファに添付されます。TPKEY_AUTOENCRYPT フラグを使用してキーをオープンすると、tpseal() を明示的に呼び出さなくても、暗号化するメッセージには自動的にマークが付きます。
注記 COBOL のアプリケーションでは、AUTOENCRYPT 設定のメンバを使用してメッセージ・バッファを暗号化します。TPKEYOPEN(3cbl) を参照してください。
次のコード例は、暗号化するメッセージ・バッファにマークを付ける方法を示しています。
コード リスト3-10 暗号化するメッセージ・バッファにマークを付ける例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY tu_key;
char *sendbuf, *rcvbuf;
.
.
.
if (tpseal(sendbuf, tu_key, 0) == -1) {
(void) fprintf(stderr, “tpseal failed tperrno=%d(%s)¥n”,
tperrno, tpstrerror(tperrno));
tpfree(rcvbuf);
tpfree(sendbuf);
tpterm();
(void) tpkey_close(tu_key, 0);
exit(1);
}
.
.
.
}
ステップ 6:メッセージを送信する
メッセージ・バッファに暗号化のマークを付けた後、以下のいずれかの C 関数または COBOL ルーチンを使用して、メッセージ・バッファを送信します。
ステップ 7:暗号化キー・ハンドルをクローズする
tpkey_close(3c) 関数または TPKEYCLOSE(3cbl) ルーチンを呼び出して、暗号化キー・ハンドルとそれに関連付けられたすべてのリソースを解放します。
メッセージ・バッファの暗号化方法
公開鍵ソフトウェアは、メッセージ・バッファが送信される直前に、メッセージを暗号化して暗号化エンベロープを添付します。暗号化エンベロープにより、ターゲット受信者はメッセージを復号化できます。封印されたバッファが複数回送信される場合は、送信のたびに暗号化が実行されます。したがって、暗号化するメッセージ・バッファにマークを付けた後で、そのメッセージ・バッファを変更することができます。
公開鍵ソフトウェアは、次の手順に従って、メッセージ・バッファの内容を暗号化し、暗号化メッセージの受信者用の暗号化エンベロープを生成します。
{ }key という表記は、key を使用して { } 内 が暗号化または復号化されることを示します。ステップ 1 では、セッション・キーを使用してメッセージ・バッファが暗号化され、ステップ 2 では、受信者の公開鍵を使用してセッション・キーが暗号化されます。
複数のメッセージ受信者について
1 つのメッセージ・バッファには、複数の暗号化エンベロープを関連付けることができます。つまり、異なる秘密鍵を持つ複数の受信者が、暗号化されたメッセージを受信し、復号化することができます。受信者となるのは、ユーザまたはプロセスです。メッセージが複数の受信者に対して暗号化されると、メッセージは一度だけ暗号化されますが、セッション・キーは各受信者の公開鍵で暗号化されます。暗号化されたメッセージには、すべての暗号化エンベロープが添付されます。
1 つのメッセージ・バッファに複数の暗号化エンベロープが関連付けられた場合、すべての暗号化エンベロープは、そのアルゴリズムに対して同じ対称鍵アルゴリズムと同じキー・サイズを使用しなければなりません。
暗号化されたメッセージの内容
暗号化されたメッセージ・バッファは、 EnvelopedData というメッセージ・タイプのバージョン 0 として、PKCS-7 形式で表現されます。BEA Tuxedo システムで使用されるメッセージ・タイプ EnvelopedData は、次の項目で構成されます。
次の図は、EnvelopedData メッセージ・タイプの場合のエンベロープの階層を示します。SignedData メッセージ・タイプは、メッセージに 1 つまたは複数のデジタル署名が関連付けられている場合にのみ、この階層に含まれます。
図 3-6 EnvelopedData メッセージ・タイプ
上の図に示すように、メッセージ・バッファは、署名することも暗号化することもできます。メッセージ・バッファに関連するデジタル署名の数と暗号化エンベロープの数の間に、関係を成立させる必要はありません。 メッセージ・バッファに対して署名と暗号化の両方が実行されると、まず、暗号化されていないデータに対する署名が生成されます。次に、添付される署名の数および署名者の ID が、バルク・データの暗号化機能により暗号化されます。 注記 署名を検証する前に、メッセージのデータを復号化するための適切な復号化キーを使用できる状態にしておく必要があります。 暗号化されたメッセージを受信するためのコードの記述 暗号化されたメッセージを受信するためのコードを記述するには、次の手順に従います。
これらの手順およびメッセージ・バッファが復号化されるしくみについては、以下の節を参照してください。
ステップ 1:復号化用のキー・ハンドルをオープンする
まず、tpkey_open(3c) 関数または TPKEYOPEN(3cbl) ルーチンを呼び出して、受信側のプロセスが、ターゲット受信者の秘密鍵および関連するデジタル証明書を使用できるようにします。受信側のプロセスとは、クライアント、サービス、サーバ・グループ、ゲートウェイ・グループ、サーバ・マシン、または複数のサーバを含むドメイン全体のことです。
アプリケーション管理者は、ATMI アプリケーションの UBBCONFIG ファイルを設定して、ATMI アプリケーションの起動時に復号化キー・ハンドルを自動的にオープンするように指定できます。この方法では、サーバごとに使用できる復号化キー・ハンドルは 1 つだけです。詳細については、プラグインによる復号化キーの初期化を参照してください。
起動時に受信側のプロセスの復号化キー・ハンドルをオープンするように ATMI アプリケーションが設定されていない場合、受信側のプロセスは自身で tpkey_open() を呼び出します。または、受信側のプロセスは、別の tpkey_open() を呼び出して、別の復号化キー・ハンドルをオープンすることもできます。
ターゲット受信者の秘密鍵にアクセスするため、受信側のプロセスは、ターゲット受信者として動作する権限があることを証明する必要があります。証明の条件は、公開鍵のプラグイン・インターフェイスのインプリメンテーションによって異なります。デフォルトの公開鍵のインプリメンテーションでは、呼び出しプロセス側が秘密のパスワードを入力する必要があります。
受信側のプロセスが tpkey_open() を呼び出してキー・ハンドルをオープンするとき、TPKEY_DECRYPT フラグを指定して、そのハンドルがメッセージ・バッファの復号化に使用されることを示します。通常、クライアントは tpinit() を呼び出した後でこの呼び出しを行い、サーバは tpsvrinit() を呼び出して初期化を行うときにこの呼び出しを行います。
次のコード例では、復号化キー・ハンドルをオープンする方法を示します。TPKEY は、atmi.h ヘッダ・ファイルで定義される特殊なデータ型です。
コード リスト3-11 復号化キー・ハンドルをオープンする例
TPKEY tu_key;
tpsvrinit(argc, argv)
int argc;
char **argv;
#endif
{
char *tu_location;
.
.
.
if (tpkey_open(&tu_key, “TOUPPER”, tu_location,
NULL, 0, TPKEY_DECRYPT) == -1) {
userlog(“Unable to open private key: %d(%s)”,
tperrno, tpstrerror(tperrno));
return(-1)
}
.
.
.
}
ステップ 2: (オプション)キー・ハンドルの情報を取得する
復号化キー・ハンドルの情報を取得して、キーの有効性を確認することができます。そのためには、tpkey_getinfo(3c) 関数または TPKEYGETINFO(3cbl) ルーチンを呼び出します。返される情報の中には、暗号サービス・プロバイダに固有の情報も含まれていますが、主要な属性は、すべてのプロバイダで共通です。
次のコード例では、復号化キー・ハンドルに関する情報を取得する方法を示します。
コード リスト3-12 復号化キー・ハンドルに関する情報を取得する例
TPKEY tu_key;
tpsvrinit(argc, argv)
int argc;
char **argv;
#endif
{
char principal_name[PNAME_LEN];
long pname_len = PNAME_LEN;
.
.
.
if (tpkey_getinfo(tu_key, “PRINCIPAL”,
principal_name, &pname_len, 0) == -1) {
(void) fprintf(stdout, “Unable to get information
about principal: %d(%s)¥n”,
tperrno, tpstrerror(tperrno));
.
.
.
exit(1);
}
.
.
.
}
ステップ 3: (オプション)キー・ハンドルの情報を変更する
復号化キー・ハンドルに関連付けられたオプション属性を設定するには、tpkey_setinfo(3c) 関数または TPKEYSETINFO(3cbl) ルーチンを呼び出します。キー・ハンドル属性は、暗号サービス・プロバイダによって異なります。
次のコード例では、復号化キー・ハンドルに関連付けられた情報を変更する方法を示します。
コード リスト3-13 復号化キー・ハンドルに関連付けられた情報を変更する例
TPKEY tu_key;
tpsvrinit(argc, argv)
int argc;
char **argv;
#endif
{
TM32U mybits = 128;
.
.
.
if (tpkey_setinfo(tu_key, “ENCRYPT_BITS”, &mybits,
sizeof(mybits), 0) == -1) {
(void) fprintf(stderr, “tpkey_setinfo failed
tperrno=%d(%s)¥n”,
tperrno, tpstrerror(tperrno));
return(1);
}
.
.
.
}
ステップ 4:復号化キー・ハンドルをクローズする
tpkey_close(3c) 関数または TPKEYCLOSE(3cbl) ルーチンを呼び出して、復号化キー・ハンドルとそれに関連付けられたすべてのリソースを解放します。
メッセージ・バッファの復号化方法
公開鍵ソフトウェアは、BEA Tuxedo のクライアント・プロセス、サーバ・プロセス、またはメッセージ・バッファの内容を読み取るシステム・プロセスに暗号化されたメッセージ・バッファがあると、そのメッセージ・バッファを自動的に検証します。復号化の自動処理を成功させるには、受信側のプロセスで、添付された暗号化エンベロープのいずれかで指定されている復号化キー (TPKEY_DECRYPT) をオープンしておく必要があります。
受信側のプロセスの代わりに動作する公開鍵ソフトウェアは、暗号化されたメッセージ・バッファを受信すると、次のタスクを実行します。
注記 添付されたデジタル署名をどれも検証できない場合、または、メッセージ・バッファを復号化できない場合、受信側のプロセスはメッセージ・バッファを受け取りません。さらに、受信側のプロセスは、メッセージ・バッファをまったく認識しません。
ただし、パイプ役として機能するシステム・プロセス (メッセージの内容は読み取らない) の場合、メッセージは復号化されません。たとえば、ブリッジおよびワークステーション・ハンドラ (WSH) は、パイプ役として機能するシステム・プロセスの例です。
WSH は、パイプ役の特殊な例です。データ依存型ルーティング用に設定された WSH は、メッセージ・バッファを受信するとそれを読み取り、バッファのルーティング方法を決定します。つまり、まず、公開鍵ソフトウェアは、受信したメッセージ・バッファのコピーを作成し、そのコピーを復号化して WSH に渡します。WSH は、受け取ったコピーを解析し、そのメッセージ・バッファをルーティングする方法を決定すると、元のメッセージ・バッファをそのまま適切なサーバにルーティングします。データ依存型ルーティングと公開鍵セキュリティとの相互運用の詳細については、データ依存型ルーティングとの互換性および相互運用性を参照してください。
入力バッファの暗号化エンベロープを破棄する
メッセージ・バッファが入力パラメータとして ATMI 関数 (tpacall() など) に渡された場合、公開鍵ソフトウェアは、メッセージにあらかじめ添付された暗号化エンベロープを破棄します。この機能により、中継プロセスで変更された元のメッセージが、ターゲット受信者側で受け取られないようにすることができます。
このプロセスの例として、次の図に示すシナリオを考えてみます。
図 3-7 暗号化された署名付きメッセージを転送する例
この例は、Manager という名前のサーバ・プロセスが、Employee というクライアント・プロセスから、暗号化された署名付きメッセージ・バッファを受信する様子を示しています。サーバは、受信したメッセージ・バッファを復号化して読み取った後で、Purchasing サービス用に署名および封印し、Purchasing に送信します。 この操作を以下に詳しく説明します。
WSH プロセスには、データ依存型ルーティングが設定されています。これについては、メッセージ・バッファの復号化方法を参照してください。公開鍵ソフトウェアは、WSH プロセスで既にオープンした復号化キーを使用して、受信したメッセージ・バッファのコピーを復号化します。次に、復号化したメッセージのコピーを WSH に渡します。WSH は、復号化されたコピーを解析してから、受信したメッセージ・バッファをそのまま Manager プロセスに転送します。
WSH プロセスにデータ依存型ルーティングが設定されていない場合、Employee プロセスは、WSH プロセスのメッセージ・バッファに対して tpseal() を呼び出す必要はありません。また、WSH プロセスも復号化キーをオープンする必要はありません。
データ依存型ルーティングが設定されているかどうかにかかわらず、WSH はデジタル署名の検証を行いません。
公開鍵ソフトウェアは、メッセージが送信される直前に、次のタスクを実行します。
出力バッファの暗号化エンベロープを置換する
メッセージ・バッファが出力パラメータとして ATMI 関数 (tpgetrply() など) に渡された場合、公開鍵ソフトウェアは、このバッファに関連付けられた暗号化の情報を削除します。削除する情報には、保留中の署名 (メッセージ・バッファに登録された署名)、およびバッファを前回使用したユーザの署名が含まれます。
この操作が正常に終了すると、新しい暗号化の情報が、新しいバッファの内容に関連付けられる場合があります。
関連項目
デジタル署名および暗号化情報の調査
公開鍵ソフトウェアでは、次の順序指定が適用されます。
プロセスは、ターゲットのメッセージ・バッファを引数に指定して tpenvelope() 関数を呼び出すことにより、この情報を取得します。tpenvelope() については、『BEA Tuxedo C リファレンス』の tpenvelope(3c) リファレンス・ページを参照してください。
デジタル署名登録要求、デジタル署名、暗号化登録要求、およびメッセージ・バッファに関連付けられている暗号化エンベロープの複数のオカレンスが同時に存在することがあります。これらのオカレンスは順番に格納され、最初の項目が 0 位置に、以降の項目は 0 に続く連続する位置に格納されます。tpenvelope() の occurrence 入力パラメータは、要求された項目を示します。occurrence の値が最後の項目の位置を過ぎると、tpenvelope() は TPENOENT エラー状態で異常終了します。TPENOENT が返されるまで tpenvelope() を繰り返し呼び出すことにより、すべての項目を調べることができます。
送信側のプロセスでは通常、デジタル署名および暗号化の情報は、メッセージが送信されるまで保留状態になっています。受信プロセスでは、デジタル署名が確認され、暗号化と解読も既に行われています。
送信側のプロセスが tpenvelope を呼び出したときの動作
送信側のプロセスが発信メッセージ・バッファを引数として tpenvelope() を呼び出すと、tpenvelope() は次のレポートを作成します。
tpenvelope() は、ステータスの情報のほか、デジタル署名または暗号化の登録要求に関連付けられたキー・ハンドルも返します。プロセスは、キー・ハンドルを引数として tpkey_getinfo(3c) 関数を呼び出し、キー・ハンドルに関する詳しい情報を取得できます。
受信側のプロセスが tpenvelope を呼び出したときの動作
プロセスがメッセージ・バッファを受信するときは、メッセージの内容だけを受信します。メッセージ・バッファに関連付けられているデジタル署名や暗号化エンベロープは受信しません。受信側のプロセスは、tpenvelope() を呼び出して、添付されたデジタル署名や暗号化エンベロープに関する情報を取得する必要があります。
受信側のプロセスが受信メッセージ・バッファを引数として tpenvelope() を呼び出すと、tpenvelope() は次のレポートを作成します。
デジタル署名は検証されました。
メッセージ・バッファの内容が変更されたため、デジタル署名は無効です。
署名者のデジタル証明書が変更されたため、デジタル署名は無効です。
署名者のデジタル証明書が取り消されたため、デジタル署名は無効です。
タイムスタンプが遠い将来の時刻を示しているため、デジタル署名は無効です。
署名者のデジタル証明書の有効期限が切れたため、デジタル署名は無効です。
タイムスタンプが古すぎるため、デジタル署名は無効です。
署名者のデジタル証明書が不明な認証局 (CA) によって発行されたため、デジタル署名は無効です。
暗号化エンベロープは有効です。
ターゲット受信者のデジタル証明書が変更されたため、暗号化エンベロープは無効です。ターゲット受信者は、メッセージ・バッファを受信しません。
ターゲット受信者のデジタル証明書が取り消されたため、暗号化エンベロープは無効です。ターゲット受信者は、メッセージ・バッファを受信しません。
ターゲット受信者のデジタル証明書の有効期限が切れたため、暗号化エンベロープは無効です。ターゲット受信者は、メッセージ・バッファを受信しません。
ターゲット受信者のデジタル証明書が不明な認証局 (CA) から発行されたため、暗号化エンベロープは無効です。ターゲット受信者は、メッセージ・バッファを受信しません。
tpenvelope() は、ステータスの情報のほか、デジタル署名または暗号化エンベロープに関連付けられたキー・ハンドルも返します。プロセスは、キー・ハンドルを引数として tpkey_getinfo(3c) 関数を呼び出し、キー・ハンドルに関する詳しい情報を取得できます。
受信側のプロセスが、メッセージ・バッファを受信した後で tpsign() を呼び出してデジタル署名要求を登録した場合、tpenvelope() は登録のステータスを TPSIGN_PENDING としてレポートします。同様に、受信側のプロセスが、メッセージ・バッファを受信した後で tpseal() を呼び出して暗号化 (封印) 要求を登録した場合は、tpenvelope() は登録のステータスを TPSEAL_PENDING としてレポートします。
受信側のプロセスが署名付きメッセージ・バッファを受信した後でその内容を変更すると、添付された署名は無効になります。その結果、tpenvelope() は署名を検証できないため、TPSIGN_TAMPERED_MESSAGE という署名ステータスをレポートします。
コンポジット署名ステータスについて
メッセージ・バッファに複数のデジタル署名がある場合、公開鍵ソフトウェアは、tpenvelope() と同等の内部関数を呼び出して、各デジタル署名の状態を調べます。次に、特定の規則に従い、複数のデジタル署名の状態を合成した「コンポジット署名ステータス」を生成します。次の表は、コンポジット署名ステータスを生成する規則を示しています。
TPSIGN_OK または TPSIGN_UNKNOWN のコンポジット署名ステータスが付いていないメッセージ・バッファは、受信されても破棄され、受信されなかったように扱われます。ATMI アプリケーションの UBBCONFIG ファイルの SIGNATURE_REQUIRED パラメータが Y (はい) に設定されている場合は、TPSIGN_OK のコンポジット署名ステータスが付いていないメッセージ・バッファを受信しても破棄され、受信されなかったように扱われます。詳細については、受信メッセージに対する署名方針の適用を参照してください。
ただし、前の段落で説明した署名付きメッセージ・バッファの処理の例外は、tpimport(3c) 関数です。tpimport(3c) 関数は、コンポジット署名ステータスとは関係なく、受信したメッセージ・バッファを送信します。
tpenvelope のコード例
次のコード例は、tpenvelope() を使用して、メッセージ・バッファに関連付けられているデジタル署名と暗号化の情報を調べる方法を示します。
コード リスト3-14 tpenvelope の使用例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY tu_key;
TPKEY sdo_key;
TPKEY output_key;
char *sendbuf, *rcvbuf;
int ret;
int occurrence = 0;
long status;
char principal_name[PNAME_LEN];
long pname_len = PNAME_LEN;
int found = 0;
.
.
.
output_key = NULL;
ret = tpenvelope(rcvbuf, 0, occurrence, &output_key,
&status, NULL, 0);
while (ret != -1) {
if (status == TPSIGN_OK) {
if (tpkey_getinfo(output_key, “PRINCIPAL”,
principal_name, &pname_len, 0) == -1) {
(void) fprintf(stdout, “Unable to get information
about principal: %d(%s)¥n”,
tperrno, tpstrerror(tperrno));
tpfree(sendbuf);
tpfree(rcvbuf);
tpterm();
(void) tpkey_close(tu_key, 0);
(void) tpkey_close(sdo_key, 0);
(void) tpkey_close(output_key, 0);
exit(1);
}
/* リソースを必ず解放する */
(void) tpkey_close(output_key, 0);
output_key = NULL;
found = 1;
break;
}
/* リソースを必ず解放する */
(void) tpkey_close(output_key, 0);
output_key = NULL;
occurrence++;
ret = tpenvelope(rcvbuf, 0, occurrence, &output_key,
&status, NULL, 0);
}
.
.
.
}
関連項目
型付きメッセージ・バッファの外部化
外部化された表現とは、通常はバッファが送信される直前にメッセージ・バッファに追加される BEA Tuxedo のヘッダ情報が含まれないメッセージ・バッファのことです。署名付きメッセージ・バッファを外部化された表現に変換すると、署名付きデータを「パス・スルー (通過)」させたり、署名付きバッファを長期間保存しておき、バッファ送信した事実を否認できないようにすることができます。また、復号化キーを使用しないで、暗号化されたメッセージ・バッファを中継プロセス経由で伝送することもできます。
外部化された表現の作成方法
プロセスは、tpexport(3c) 関数を呼び出して、型付きメッセージ・バッファを外部化された表現に変換します。メッセージ・バッファに関連付けられた保留状態の署名は、そのメッセージ・バッファが ATMI 関数によって別のプロセスに送信された場合のように、tpexport() が呼び出されたときに生成されます。同様に、メッセージ・バッファに関連付けられた保留中の封印は、そのメッセージ・バッファが ATMI 通信関数によって別のプロセスに送信された場合のように、tpexport() が呼び出されたときに生成されます。
外部化された表現のメッセージ・バッファは、バイナリ形式の PKCS-7 形式で保存されます。文字列で指定する必要がある場合、呼び出しプロセスは、TPEX_STRING フラグを指定して tpexport() を呼び出す必要があります。
注記 外部化された表現の型付きメッセージ・バッファを作成する機能は、公開鍵セキュリティに固有のものではありません。プロセスは、tpexport() を呼び出して型付きメッセージ・バッファを外部化することができます。メッセージ・バッファに対してデジタル署名または暗号化のマークが付けられているかどうかは無関係です。
外部化された表現の変換方法
受信側のプロセスは、tpimport(3c) 関数を呼び出して、外部化された表現のメッセージ・バッファを型付きメッセージ・バッファに変換します。tpimport() 関数も、必要に応じて復号化を行い、関連するデジタル署名があれば検証します。
tpexport および tpimport のコード例
次のコード例は、tpexport() を使用して型付きメッセージ・バッファを外部化された表現に変換する方法、および tpimport() を使用して外部化された表現を型付きメッセージ・バッファに戻す方法を示します。
コード リスト3-15 tpexport および tpimport の使用例
static void hexdump _((unsigned char *, long));
#define MAX_BUFFER 80000
main(argc, argv)
int argc;
char *argv[];
#endif
{
char *databuf;
char exportbuf[MAX_BUFFER];
long exportbuf_size = 0;
char *importbuf = NULL;
long importbuf_size = 0;
int go_on = 1;
.
.
.
exportbuf_size = 0;
while (go_on == 1) {
if (tpexport(databuf, 0, exportbuf, &exportbuf_size, 0)
== -1) {
if (tperrno == TPELIMIT) {
printf(“%d tperrno is TPELIMIT, exportbuf_size=%ld¥n”,
__LINE__, exportbuf_size);
if (exportbuf_size > MAX_BUFFER) {
return(1);
}
}
else {
printf(“tpexport(%d) failed: tperrno=%d(%s)¥n”,
__LINE__, tperrno, tpstrerror(tperrno));
return(1);
}
}
else {
go_on = 0;
}
}
.
.
.
hexdump((unsigned char *) exportbuf, (long) exportbuf_size);
if (tpimport(exportbuf, exportbuf_size, &importbuf,
&importbuf_size, 0) == -1) {
printf(“tpimport(%d) failed: tperrno=%d(%s)¥n”,
__LINE__, tperrno, tpstrerror(tperrno));
return(1);
}
.
.
.
}
関連項目
![]() |
![]() |
![]() |
![]() |
||
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |