2.3 CryptoAPIでの電子証明書の取り扱い
電子証明書には、証明書ストアを介してアクセスします。証明書に関連する秘密鍵と公開鍵は、CSP(Cryptographic Service Provider)が管理するキーデータベースにあります。
電子証明書にアクセスする手順は、以下のようになります。
電子証明書にアクセスする手順は、以下のようになります。
- CSPのハンドルを取得する
- 証明書ストアをオープンする。
- 必要な証明書を取り出し、利用する。
2.3.1 CSPのハンドルを取得する
CSPのハンドルは、以下の方法で取得します。
注意)
ここでの例では、既定のCSPを利用しています。既定のCSPは、コンピュータやユーザーごとに違っているかもしれません。1.12 CSP(CryptoGraphy Service Provider)についてを参照して目的のCSPを選択してください。
注意)
ここでの例では、既定のCSPを利用しています。既定のCSPは、コンピュータやユーザーごとに違っているかもしれません。1.12 CSP(CryptoGraphy Service Provider)についてを参照して目的のCSPを選択してください。
// CSPハンドルの取得 HCRYPTPROV hProv; if(!CryptAcquireContext( &hProv, // CSPのハンドルです NULL, // 現ユーザーのログイン名を使います NULL, // デフォルトのプロバイダーを使います PROV_RSA_FULL, // 暗号・復号のタイプです NULL)) { fprintf(stderr, "CryptAcquireContext error\n"); return 1; }
第5引数には、キーコンテナーへのフラグを指定します。すでに希望のキーコンテナーが存在している場合は、このコードで問題なく動作します。しかし、それが存在しない場合は、エラーになりますので、以下のコードを利用します。
//CSPハンドルの取得 HCRYPTPROV hProv; if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, NULL)) { if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { fprintf(stderr, "CryptAcquireContext error\n"); return 1; } }
2.3.2 証明書ストアをオープンする
システムの証明書ストアをオープンします。
システムの「個人」の証明書ストアに格納された証明書を対象にないます。
システムの「個人」の証明書ストアに格納された証明書を対象にないます。
// 証明書ストアーのオープン HCERTSTORE hStore; hStore = CertOpenSystemStore( hProv, // CSPのハンドル "MY"); // 「個人」の証明書ストア if(!hStore) { fprintf(stderr, "CertOpenSystemStore error\n"); return 2; }
第1引数には、CSPのハンドル
第2引数には、証明書ストアの指定します。この値は、以下の通り設定します。
第2引数には、証明書ストアの指定します。この値は、以下の通り設定します。
個人 "MY" 他の人 "ADDRESSBOOK" 中間証明機関 "CA" 信頼されたルート証明機関 "ROOT"関数の返値として証明書ストアのハンドルが戻ります。
2.3.3 電子証明書を取り出す
電子証明書を指定する証明書ストアから取り出します。電子証明書は、その電子証明書の発行機関とシリアル番号でユニークになります。そのため、希望の電子証明書を証明書ストアから取り出す場合は、発行機関とシリアル番号を指定します。
ただし、ここでは説明を簡単にするため、電子証明書の所有者を指定して取り出します。また、同じ所有者を持つ電子証明書が多数格納されていた場合には、はじめに見つかった電子証明書を取り出します。
本来であれば、多数の電子証明書から対象の電子証明書を間違いなく取り出すような工夫をしなければなりません。
ただし、ここでは説明を簡単にするため、電子証明書の所有者を指定して取り出します。また、同じ所有者を持つ電子証明書が多数格納されていた場合には、はじめに見つかった電子証明書を取り出します。
本来であれば、多数の電子証明書から対象の電子証明書を間違いなく取り出すような工夫をしなければなりません。
//電子証明書の取り出し PCCERT_CONTEXT pcCert; pcCert = CertFindCertificateInStore( hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, L"検索する証明書の所有者名に書換", NULL); if(!pcCert) { fprintf(stderr, "CertFindCertificateInStore error\n"); return 3; }
第1引数には、証明書ストアのハンドルを与えます。
第2引数には、電子証明書のエンコードのタイプを設定します。しかしながら、現在は上記のタイプだけが利用可能ですので、常にこのように指定します。
第3引数には、検索のタイプによってフラグを指定しますが、今回の検索では、0(ゼロ)を指定します。
第4引数には、電子証明書の所有者名(サブジェクト)検索の指定をします。サブジェクトに記載された情報は、この関数によってヌル端末文字列に変換されてから比較されます。
第5引数には、検索の文字(所有者名)を指定します。ここの文字列をお手持ちの電子証明書のサブジェクトに示された文字列に変更してください。
第5引数には、同じ検索条件で検索される電子証明書が複数個あった場合に利用しますが、今回の例では、初めに検索された電子証明書を利用しますので、NULLを指定します。
検索された電子証明書のポインターが戻ります。
見つからなかった場合は、NULLが戻ります。
これ以降は、この電子証明書のポインターを使って暗号化や電子署名の処理を行います。
参考:
電子証明書をGUIで選択するには、2.5.3電子証明書を選択する を参照してください。ただし、ここで説明している方法は、WidowsXPおよびWindows2003Serverにのみ利用できます。小社では、それ以前のWindowsでも利用可能な電子証明書選択関数を作成し公開しています。Windows98で利用可能なダイアログ を参照してください。
第2引数には、電子証明書のエンコードのタイプを設定します。しかしながら、現在は上記のタイプだけが利用可能ですので、常にこのように指定します。
第3引数には、検索のタイプによってフラグを指定しますが、今回の検索では、0(ゼロ)を指定します。
第4引数には、電子証明書の所有者名(サブジェクト)検索の指定をします。サブジェクトに記載された情報は、この関数によってヌル端末文字列に変換されてから比較されます。
第5引数には、検索の文字(所有者名)を指定します。ここの文字列をお手持ちの電子証明書のサブジェクトに示された文字列に変更してください。
第5引数には、同じ検索条件で検索される電子証明書が複数個あった場合に利用しますが、今回の例では、初めに検索された電子証明書を利用しますので、NULLを指定します。
検索された電子証明書のポインターが戻ります。
見つからなかった場合は、NULLが戻ります。
これ以降は、この電子証明書のポインターを使って暗号化や電子署名の処理を行います。
参考:
電子証明書をGUIで選択するには、2.5.3電子証明書を選択する を参照してください。ただし、ここで説明している方法は、WidowsXPおよびWindows2003Serverにのみ利用できます。小社では、それ以前のWindowsでも利用可能な電子証明書選択関数を作成し公開しています。Windows98で利用可能なダイアログ を参照してください。
2.3.4 後始末
電子証明書の検索などで受け取った、電子証明書のポインターは、不要になったなら開放しなければなりません。以下の方法で、開放してください。
第2引数には、証明書ストアをクローズする際のフラグを指定します。ここにCERT_CLOSE_STORE_FORCE_FLAGを指定しますと、その証明書ストアで利用している電子証明書を全て開放します。
CSPも同様にクローズします。
第2引数には、必ず0(ゼロ)を指定します。0以外の場合は、関数がエラーを戻し、CSPは開放されません。
// 後始末 CertFreeCertificateContext(pcCert);また、証明書ストアも開放します。
CertCloseStore(hStore, 0);第1引数には、証明書ストアのハンドルを指定します。
第2引数には、証明書ストアをクローズする際のフラグを指定します。ここにCERT_CLOSE_STORE_FORCE_FLAGを指定しますと、その証明書ストアで利用している電子証明書を全て開放します。
CSPも同様にクローズします。
CryptReleaseContext(hProv, 0);第1引数には、CSPのハンドルを指定します。
第2引数には、必ず0(ゼロ)を指定します。0以外の場合は、関数がエラーを戻し、CSPは開放されません。
2.3.5 全ての証明書を取り出す
電子証明書を検索する関数(CertFindCertificateInStore)を使って格納された電子証明書を全て取り出す例を示します。また、取り出した電子証明書のサブジェクトを表示させます。
// 全ての電子証明書の取り出し PCCERT_CONTEXT pcCert; char name[100]; pcCert = NULL; while(pcCert = CertFindCertificateInStore( hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, // 2005.06.08 修正 "", // 2005.06.08 修正 pcCert)) { CertNameToStr( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &pcCert->pCertInfo->Subject, CERT_SIMPLE_NAME_STR, name, 100); printf("Name: %s\n", name); }
第4引数に、「全ての電子証明書」の意味でCERT_FIND_ANYをセットします。
第5引数には、特にしてするデータがありませんので、NULLを指定します。
第6引数には、直前の関数呼び出しで得られた証明書ポインターを与えます。各々の証明書ポインターは、この関数内で開放されますので開放する必要はありません。
取り出した、電子証明書のサブジェクトをCertNameToStrを使って文字列に変換して表示させます。
第5引数には、特にしてするデータがありませんので、NULLを指定します。
第6引数には、直前の関数呼び出しで得られた証明書ポインターを与えます。各々の証明書ポインターは、この関数内で開放されますので開放する必要はありません。
取り出した、電子証明書のサブジェクトをCertNameToStrを使って文字列に変換して表示させます。
2.3.6 サンプルのコード
「個人」の証明書ストアにインストールされている電子証明書を全て表示するサンプルです。
サンプルコードの商業利用および転載を禁止します。
サンプルコードの商業利用および転載を禁止します。
2.3.7 ご質問・ご要望
ご質問やご要望は、こちらからお送りください。(匿名でも可能です。)
(記載の会社名および製品名は、各社の登録商標および商標です。)