|
|
|
|
|
暗号化されたメッセージの送信と受信
メッセージ・ベースの暗号化では、エンド・ツー・エンドでデータの機密性が保たれます。この機能のしくみについては、図の「ATMI PKCS-7 のエンド・ツー・エンドの暗号化」 を参照してください。
メッセージは、送信側のプロセスを離れる直前に暗号化され、その状態は受信側のプロセスで受信されるまで保持されます。メッセージは、オペレーティング・システムのメッセージ・キュー、システム・プロセス、ディスク・ベース・キューなどの中継ポイントのほか、サーバ間のネットワーク・リンクで転送される間もオペークです。
暗号化されたメッセージを送信するためのコードの作成
次のフローチャートでは、暗号化されたメッセージを送信するコードを記述する手順を示します。
暗号化されたメッセージの送信手順
これらの手順およびメッセージ・バッファが暗号化されるしくみについては、以下の節を参照してください。 ステップ 1:暗号化用のキー・ハンドルをオープンする まず、tpkey_open(3c) 関数または TPKEYOPEN(3cbl) ルーチンを呼び出して、送信側のプロセスが、ターゲット受信者のデジタル証明書を使用できるようにします。ターゲット受信者とは、クライアント、サービス、サーバ・グループ、ゲートウェイ・グループ、サーバ・マシン、または複数のサーバを含むドメイン全体のことです。 送信側のプロセスが tpkey_open() を呼び出してキー・ハンドルをオープンするとき、TPKEY_ENCRYPT フラグまたは TPKEY_AUTOENCRYPT フラグを指定して、そのキー・ハンドルがメッセージ・バッファの暗号化に使用されることを示します。通常、クライアントは tpinit() を呼び出した後でこの呼び出しを行い、サーバは tpsvrinit() を呼び出して初期化を行うときにこの呼び出しを行います。 TPKEY_AUTOENCRYPT フラグを使用してキー・ハンドルをオープンすると、暗号化の自動処理が可能になります。以降、送信側のプロセスは、メッセージ・バッファが送信されるたびに、メッセージ・バッファを自動的に暗号化します。TPKEY_AUTOENCRYPT フラグを使用すると、次の 3 つの利点があります。
次のコード例では、暗号化キー・ハンドルをオープンする方法を示します。TPKEY は、atmi.h ヘッダ・ファイルで定義される特殊なデータ型です。
暗号化キー・ハンドルをオープンする例
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 の値が自動的に調整されます。
次のコード例では、暗号化キー・ハンドルに関する情報を取得する方法を示します。
暗号化キー・ハンドルに関する情報を取得する例
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) ルーチンを呼び出します。キー・ハンドル属性は、暗号サービス・プロバイダによって異なります。
次のコード例では、暗号化キー・ハンドルに関連付けられた情報を変更する方法を示します。
暗号化キー・ハンドルに関連付けられた情報を変更する例
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) を参照してください。
次のコード例は、暗号化するメッセージ・バッファにマークを付ける方法を示しています。
暗号化するメッセージ・バッファにマークを付ける例
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 つまたは複数のデジタル署名が関連付けられている場合にのみ、この階層に含まれます。
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 ヘッダ・ファイルで定義される特殊なデータ型です。
復号化キー・ハンドルをオープンする例
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) ルーチンを呼び出します。返される情報の中には、暗号サービス・プロバイダに固有の情報も含まれていますが、主要な属性は、すべてのプロバイダで共通です。
次のコード例では、復号化キー・ハンドルに関する情報を取得する方法を示します。
復号化キー・ハンドルに関する情報を取得する例
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) ルーチンを呼び出します。キー・ハンドル属性は、暗号サービス・プロバイダによって異なります。
次のコード例では、復号化キー・ハンドルに関連付けられた情報を変更する方法を示します。
復号化キー・ハンドルに関連付けられた情報を変更する例
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() など) に渡された場合、公開鍵ソフトウェアは、メッセージにあらかじめ添付された暗号化エンベロープを破棄します。この機能により、中継プロセスで変更された元のメッセージが、ターゲット受信者側で受け取られないようにすることができます。
このプロセスの例として、次の図に示すシナリオを考えてみます。
暗号化された署名付きメッセージを転送する例
この例は、Manager という名前のサーバ・プロセスが、Employee というクライアント・プロセスから、暗号化された署名付きメッセージ・バッファを受信する様子を示しています。サーバは、受信したメッセージ・バッファを復号化して読み取った後で、Purchasing サービス用に署名および封印し、Purchasing に送信します。 この操作を以下に詳しく説明します。
WSH プロセスには、データ依存型ルーティングが設定されています。これについては、「メッセージ・バッファの復号化方法」を参照してください。公開鍵ソフトウェアは、WSH プロセスで既にオープンした復号化キーを使用して、受信したメッセージ・バッファのコピーを復号化します。次に、復号化したメッセージのコピーを WSH に渡します。WSH は、復号化されたコピーを解析してから、受信したメッセージ・バッファをそのまま Manager プロセスに転送します。
WSH プロセスにデータ依存型ルーティングが設定されていない場合、Employee プロセスは、WSH プロセスのメッセージ・バッファに対して tpseal() を呼び出す必要はありません。また、WSH プロセスも復号化キーをオープンする必要はありません。
データ依存型ルーティングが設定されているかどうかにかかわらず、WSH はデジタル署名の検証を行いません。
プロセスがメッセージ・バッファを受信するときは、メッセージの内容だけを受信します。そのメッセージ・バッファに関連付けられているデジタル署名や暗号化エンベロープは受信しません。
公開鍵ソフトウェアは、メッセージが送信される直前に、次のタスクを実行します。
出力バッファの暗号化エンベロープを置換する
メッセージ・バッファが出力パラメータとして ATMI 関数 (tpgetrply() など) に渡された場合、公開鍵ソフトウェアは、このバッファに関連付けられた暗号化の情報を削除します。削除する情報には、保留中の封印 (メッセージ・バッファに登録された受信者の封印)、および前回使用したバッファの封印が含まれます。
この操作が正常に終了すると、新しい暗号化の情報が、新しいバッファの内容に関連付けられる場合があります。
関連項目
|
|
|
|
|
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|