|
|
署名付きメッセージの送信と受信
メッセージ・ベースのデジタル署名では、エンド・ツー・エンドの認証が行われ、メッセージの完全性が保たれます。この機能のしくみについては、図の「ATMI PKCS-7 のエンド・ツー・エンドのデジタル署名」 を参照してください。
ATMI のメッセージ・バッファにデジタル署名を追加するには、送信側のプロセスまたはユーザがメッセージ・バッファに署名します。この署名には、メッセージ・バッファの内容から得た、暗号法的に安全なチェックサムと、署名者のローカル・クロックに基づいたタイムスタンプが含まれています。
このメッセージ・バッファに対するアクセス権がある場合は、署名者の署名が本物であるかどうか、メッセージ・バッファの内容が変更されていないかどうか、およびタイムスタンプが検証者のローカル・クロックで受け付ける時刻の範囲内かどうかを検証できます。さらに、時間に依存しない、サード・パーティによる検証を行うと、メッセージの非否認性を保証できます。つまり、送信側のプロセスまたはユーザは、メッセージを送信した事実を否認したり、メッセージが改ざんされたと主張することはできません。
署名付きメッセージを送信するためのコードの作成
次のフローチャートでは、署名付きメッセージを送信するコードを記述する手順を示します。
署名付きメッセージの送信手順
これらの手順およびメッセージ・バッファが署名されるしくみについては、以下の節を参照してください。 ステップ 1:デジタル署名用のキー・ハンドルをオープンする まず、tpkey_open(3c) 関数または TPKEYOPEN(3cbl) ルーチンを呼び出して、送信側のプロセスが、署名者の秘密鍵および関連するデジタル証明書を使用できるようにします。秘密鍵は厳しくセキュリティ保護されているため、秘密鍵を所有することは、署名者の ID を所有することと同等の意味があります。 署名者の秘密鍵にアクセスするため、送信側のプロセスは、署名者として動作する権限があることを証明する必要があります。証明の条件は、公開鍵のプラグイン・インターフェイスのインプリメンテーションによって異なります。デフォルトの公開鍵のインプリメンテーションでは、呼び出しプロセス側が秘密のパスワードを入力する必要があります。 送信側のプロセスが tpkey_open() を呼び出してキー・ハンドルをオープンするとき、TPKEY_SIGNATURE フラグまたは TPKEY_AUTOSIGN フラグを指定して、そのキー・ハンドルがメッセージ・バッファのデジタル署名に使用されることを示します。通常、クライアントは tpinit() を呼び出した後でこの呼び出しを行い、サーバは tpsvrinit() を呼び出して初期化を行うときにこの呼び出しを行います。 TPKEY_AUTOSIGN フラグを使用してキー・ハンドルをオープンすると、署名の自動生成が可能になります。以降、送信側のプロセスは、メッセージ・バッファが送信されるたびに、メッセージ・バッファに自動的に署名します。TPKEY_AUTOSIGN フラグを使用すると、次の 3 つの利点があります。
次のコード例では、署名者のキー・ハンドルをオープンする方法を示します。TPKEY は、atmi.h ヘッダ・ファイルで定義される特殊なデータ型です。
署名者のキー・ハンドルをオープンする例
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 キー属性によって制御されます。
デフォルトの公開鍵のインプリメンテーションでは、上記のアルゴリズムおよびキー・サイズの範囲で作成されたデジタル証明書の署名だけが認識されます。
次のコード例では、署名者のキー・ハンドルに関する情報を取得する方法を示します。
署名者のキー・ハンドルに関する情報を取得する例
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) ルーチンを呼び出します。キー・ハンドル属性は、暗号サービス・プロバイダによって異なります。
次のコード例では、署名者のキー・ハンドルに関連付けられた情報を変更する方法を示します。
署名者のキー・ハンドルに関連付けられた情報を変更する例
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 設定のメンバを使用してデジタル署名を作成します。TPKEYOPEN(3cbl) を参照してください。
次のコード例は、デジタル署名を添付するメッセージ・バッファにマークをつける方法を示しています。
デジタル署名を添付するメッセージ・バッファにマークを付ける例
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 というメッセージ・タイプによって包含されています。
SignedData メッセージ・タイプ
署名付きメッセージの受信方法 署名付きメッセージ・バッファを受信するための ATMI アプリケーション・コードは必要ありません。公開鍵ソフトウェアは、添付されたデジタル署名を自動的に検証し、そのメッセージを受信側のプロセスに渡します。 受信側のプロセスの代わりに動作する公開鍵ソフトウェアは、署名付きメッセージ・バッファを受信すると、次のタスクを実行します。
digest[ ] という表記は、メッセージ・ダイジェスト・アルゴリズム (この場合は MD5 または SHA-1) を使用して [ ] 内のハッシュ値が計算されることを示します。
注記 添付されたデジタル署名をどれも検証できない場合、受信側のプロセスは、メッセージ・バッファを受け取りません。さらに、受信側のプロセスは、メッセージ・バッファをまったく認識しません。
デジタル署名を検証する
公開鍵ソフトウェアは、クライアント・プロセス、サーバ・プロセス、またはメッセージ・バッファの内容を読み取るシステム・プロセスに署名付きメッセージ・バッファがあると、メッセージに添付されたデジタル署名を自動的に検証します。ただし、パイプ役として機能するシステム・プロセス (メッセージの内容は読み取らない) の場合、メッセージに添付されたデジタル署名は検証されません。たとえば、ブリッジおよびワークステーション・ハンドラ (WSH) は、パイプ役として機能するシステム・プロセスの例です。
署名に記録されたタイムスタンプは、非同期のクロックに基づいているため、特に、PC またはパーソナル・コンピュータで署名が行われた場合は、完全に信頼できません。ただし、遠い過去または将来を示すタイムスタンプが記録された要求を、サーバ側で拒否することができます。タイムスタンプに基づいて要求を拒否する機能を使用すると、リプレイ攻撃から保護することができます。
入力バッファの署名を検証および送信する
メッセージ・バッファが入力パラメータとして ATMI 関数 (tpacall() など) に渡された場合、公開鍵ソフトウェアは、メッセージにあらかじめ添付された署名を検証してから、メッセージを転送します。この動作によって、複数のプロセスからの署名を付けた情報を、安全かつ確実に転送することができます。
サーバ側で、受信したメッセージ・バッファを変更して転送すると、元の署名は無効になります。この場合、公開鍵ソフトウェアは、無効な署名を検出して破棄します。このプロセスの例として、「入力バッファの暗号化エンベロープを破棄する」を参照してください。
出力バッファの署名を置換する
メッセージ・バッファが出力パラメータとして ATMI 関数 (tpgetrply() など) に渡された場合、公開鍵ソフトウェアは、このバッファに関連付けられた署名の情報を削除します。削除する情報には、保留中の署名 (メッセージ・バッファに登録された署名)、およびバッファを前回使用したユーザの署名が含まれます。
この操作が正常に終了すると、新しい署名の情報が新しいバッファの内容に関連付けられる場合があります。
関連項目
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|