前のページ <<< >>> 次のページ

5.2 電子証明書の拡張情報とCryptoAPI

 拡張情報は、電子証明書のバージョンが3の場合にのみ現れるフィールドです。拡張情報は、Extentionsデータ型として既定されています。以下では、そのデータ型とそこに含まれる情報の扱い方について説明します。拡張情報の詳細は、4.2 電子証明書の拡張情報で説明しています。

5.2.1 サンプルについて

 この章からサンプルでは、共通の関数を定義し、サンプルではできるだけアプリケーションの全体を表示できるようにしました。共通関数はこちらからダウンロードできます。
なお、共通関数の転載・転用はお断りいたします。共通関数のご利用は、個人が電子証明書の取り扱い等の学習用途に限って許諾いたします。

5.2.2 拡張情報のポインター

 拡張情報は、struct _CERT_INFOのメンバーとして宣言されています。拡張情報の数がcExtentionに格納され、それぞれの要素がrgExtention配列に格納されています。rgExtentionは、以下のように宣言されています。
typedef struct _CERT_EXTENSION {
    LPSTR               pszObjId;
    BOOL                fCritical;
    CRYPT_OBJID_BLOB    Value;
} CERT_EXTENSION, *PCERT_EXTENSION;
pszObjIdは、拡張情報の種類を表すオブジェクト識別子です。
fCriticalは、拡張情報の重要・非重要を表します。
Valueは、拡張情報のないようです。BERエンコードされたバイナリー値が格納されています。
以下のコードでは、拡張情報の数を確認し、そのデータの種類(オブジェクト識別子)を表示します。
#include <CertLib.h>

int _tmain(int argc, _TCHAR* argv[])
{
HCRYPTPROV      hProv;
HCERTSTORE      hStore;
PCCERT_CONTEXT  pcCert;

// 証明書ストアのオープンと電子証明書の選択
if(OpenAndGetCertificate(&hProv, &hStore, &pcCert) < 0)
{
    fprintf(stderr, "Error\n");
    return 1;
}

// 拡張情報
int     cExt;
printf("Num = %d\n", (cExt = pcCert->pCertInfo->cExtension));
for(int i = 0; i < cExt; i++)
{
printf("%2d: %s\n", i, pcCert->pCertInfo->rgExtension[i].pszObjId);
}

// 後始末
CertFreeCertificateContext(pcCert);
CertCloseStore(hStore, 0);
CryptReleaseContext(hProv, 0);

return 0;
}
結果(例)は、以下のようになります。
Num = 10
 0: 2.5.29.15
 1: 1.2.840.113549.1.9.15
 2: 2.5.29.14
 3: 1.3.6.1.4.1.311.21.7
 4: 2.5.29.35
 5: 2.5.29.31
 6: 2.5.29.37
 7: 2.5.29.32
 8: 1.3.6.1.4.1.311.21.10
 9: 2.5.29.17

5.2.3 認証局識別子 (Authority Key Identifier)

 Authority Key Identifierは、オブジェクト識別子が "2.5.29.35" のフィールドです。これをもったフィールドのデータを確認します。
#include "stdafx.h"
#include <CertLib.h>

int _tmain(int argc, _TCHAR* argv[])
{
HCRYPTPROV      hProv;
HCERTSTORE      hStore;
PCCERT_CONTEXT  pcCert;

// 証明書ストアのオープンと電子証明書の選択
if(OpenAndGetCertificate(&hProv, &hStore, &pcCert) < 0)
{
    fprintf(stderr, "Error\n");
    return 1;
}

// 拡張情報
int     cExt;
char    pstr[2000];
DWORD   cstr = 2000;

printf("Num = %d\n", (cExt = pcCert->pCertInfo->cExtension));
for(int i = 0; i < cExt; i++)
{
    printf("%2d: %s\n", i, pcCert->pCertInfo->rgExtension[i].pszObjId);

    if(!strcmp(pcCert->pCertInfo->rgExtension[i].pszObjId, "2.5.29.35"))
    {
        printf("Authority Key Identifier\n%s\n",
                pcCert->pCertInfo->rgExtension[i].fCritical ?
                                    "critical" : "non-critical");
        CryptBinaryToString(
                    pcCert->pCertInfo->rgExtension[i].Value.pbData,
                    pcCert->pCertInfo->rgExtension[i].Value.cbData,
                    CRYPT_STRING_HEXASCIIADDR, pstr, &cstr);
        printf("Value =\n%s\n", pstr);
    }
}

// 後始末
CertFreeCertificateContext(pcCert);
CertCloseStore(hStore, 0);
CryptReleaseContext(hProv, 0);

return 0;
}
結果(例)は、以下のようになります。
Num = 10
 0: 2.5.29.15
 1: 1.2.840.113549.1.9.15
 2: 2.5.29.14
 3: 1.3.6.1.4.1.311.21.7
 4: 2.5.29.35
Authority Key Identifier
non-critical
Value =
0000    30 16 80 14 ee 79 91 1d  88 68 53 fb d4 69 06 bc   0....y...hS..i..
0010    00 ef 80 46 b6 17 f3 74                            ...F...t

 5: 2.5.29.31
 6: 2.5.29.37
 7: 2.5.29.32
 8: 1.3.6.1.4.1.311.21.10
 9: 2.5.29.17
結果を見ますと、選択した電子証明書には認証局識別子が含まれていて、ノンクリチカルとされていて、23バイトの値(Value)をもっていることがわかります。この値は、AuthorKeyIdentifierをBERエンコードした値です。この値のデコードは、先頭から1オクテット(バイト)ごとに行います。
先頭の0x30は、SEQUENCEを示しています。次の0x16は、そのSEQUENCEの長さが16オクテットであるとしています。続く3番目のオクテットがコンテキストを特定するための情報で、その下5ビットが番号です。サンプルの結果では、その番号が0(ゼロ)ですので値は、keyIdentifierであることがわかります。次のオクテットは、その値の長さで、14バイトです。残りのデータが14オクテットですので、それ以外の情報を持っていないことがわかります。
AuthorityKeyIdentifierの詳細は、4.2.3認証局識別子を参照してください。

5.2.4 サブジェクト鍵識別子 (Subject Key Identifier)

 SubjectKeyIdentifierは、オブジェクト識別子が "2.5.29.14" のフィールドです。前項の識別子を変更すると同様の結果を得られます。
結果のみを表示します。詳細は、サンプルで確認してください。
 2: 2.5.29.14
Subject Key Identifier
non-critical
Value =
0000 04 14 65 93 92 1f 8c 5d 54 cc 9a 82 5e 9d 0c 6a   ..e....]T...^..j
0010 92 7b 45 83 b2 d1                                 .{E...
結果を確認しますと、先頭が0x04です。これは、OCTET STRINGを表しています。次のオクテットが0x14ですので、データは、3オクテットめから20オクテットあることがわかります。

5.2.5 鍵用途 (Key Usage)

 Key Usageは、オブジェクト識別子が""のフィールドです。
同様に結果だけを確認します。詳細は、サンプルで確認してください。
 0: 2.5.29.15
Key Usage
non-critical
Value =
0000    03 02 05 a0                                        ....
結果を確認しますと、先頭オクテットが0x03ですのでBIT STREAMであることがわかります。2オクテットめから、データは2オクテットであることがわかります。また、BIT STREAMは、可変長のビット列を扱えるため未使用ビット数がデータ部の先頭にあります。上記の結果では、0x05ビット分が未使用ですので、2番目のデータの下位から5ビット分を削除して上位の3ビットだけを利用します。すると、この場合のビット列は、’101B’となります。このことから、この電子証明書の鍵は、digitalSignature(ビット0)とKeyEncipherment(ビット2)に利用できることがわかります。しかしながら、重要フラグは、ノンクリチカルですので、この内容は無視してもかまいません。

5.2.6 証明書ポリシー (Certificate Polices)

 証明書ポリシーは、その電子証明書が発行されたときに基づいて、電子証明書が使用されてよい目的が示されています。
結果のみを表示します。
 7: 2.5.29.32
Certificate Policy
non-critical
Value =
0000    30 4c 30 4a 06 0a 02 83  38 8c 9c 04 0c 01 64 0a   0L0J....8.....d.
0010    30 3c 30 3a 06 08 2b 06  01 05 05 07 02 01 16 2e   0<0:..+.........
0020    68 74 74 70 3a 2f 2f 63  65 72 74 2e 54 72 75 73   http://cert.Trus
0030    74 53 53 2e 6a 70 2f 54  72 75 73 74 53 6f 66 74   tSS.jp/TrustSoft
0040    53 79 73 43 41 38 5f 43  50 53 2e 70 64 66         SysCA8_CPS.pdf
結果を確認しますと、最初のオクテットが0x30ですので、SEQUENCEです。これは、certificatePolicesのデータで長さが0x4cです。このデータは、SEQUENCEのPolicyInformationで構成されますので、第3オクテットも0x30となり、この大きさが0x4aですのでこれ以外にPolicyInformationは存在しません。
PolicyInformationは、オブジェクト識別氏とQualifierで構成されています。第5オクテットがオブジェクト識別子でることを示していて、その大きさは、0x0aオクテットです。この値をデコードすると、"0.2.440.200196.12.1.100.10"となります。これは、TrustSoftSysCA8という認証機関のオブジェクト識別子です。
実際の情報は、第17オクテットから開始するSEQUENCEにあります。さらにその内部にはPolicyQualifierInfo SEQUENCEがあり、その長さが0x3aです。これは、オブジェクト識別子とqualifierで構成されています。このOBJECT IDENTIFIERをデコードすると、"1.3.6.1.5.5.7.2.1"となります。これは、CPSであることを表していますので、qualifierは、CSPuriです。
そのデータは、第31オクテットから開始されています。0x16は、IA5StringですのでそのままURIとして解釈できます。その長さは、0x2eで"http://cert.TrustSS.jp/TrustSoftSysCA8_CPS.pdf"がQualifierとなります。

5.2.7 サブジェクト代替名 (Subject Altanative Name)

 Subject Altanative Nameは、追加の識別情報です。
結果のみを記します。
Subject Antanatve Name
non-critical
Value =
0000    30 36 a0 24 06 0a 2b 06  01 04 01 82 37 14 02 03   06.$..+.....7...
0010    a0 16 0c 14 4d 61 73 74  65 72 38 32 31 40 54 72   ....Master821@Tr
0020    75 73 74 53 53 2e 6a 70  81 0e 61 62 63 64 40 65   ustSS.jp..abcd@e
0030    66 67 68 69 68 2e 6a 70                            fghij.jp
結果から、0x30から開始するデータは、SubjectAltNameを表し、そのデータの長さは、0x36であることがわかります。第4オクテットからはじめの情報が、24オクテットで、2つめの情報が、第0x29オクテットから開始する0x0eオクテットの情報であるkとがわかります。
1番目の情報は、第3オクテットからGenerarlNameのotherName情報であることがわかります。また、2つめの情報は、rfc822Nameであることがわかります。

5.2.8 拡張鍵用途  (Entended Key Usage)

 拡張鍵用途は、鍵用途(Key Usage)フィールドの追加または代わりの情報です。
結果のみを記します。
 6: 2.5.29.37
Extended Key Usage
non-critical
Value =
0000    30 16 06 08 2b 06 01 05  05 07 03 04 06 0a 2b 06   0...+.........+.
0010    01 04 01 82 37 0a 03 04                            ....7...
 この結果から、拡張鍵用途には、2つのオブジェクト識別子が含まれていることがわかります。それぞれをデコードすると、"1.3.6.1.5.5.7.3.4"と"1.3.6.1.4.1.311.10.3.4"となり、それぞれ「電子メールの保護」と「暗号化ファイルシステム」を意味します。

5.2.9 サンプル

 電子証明書の拡張情報を表示させるサンプルです。
このサンプルのコンパイルには、Crypt32.libとともに、Cryptui.libをリンクする必要があります。
 サンプルの商業利用および転載は禁止します。

5.2.10 ご質問・ご要望

 ご質問やご要望は、こちらからお送りください。(匿名でも可能です。)

PDF-Tools
PDFおよびPDF/Aを作成・編集などができるライブラリ
128ビットの暗号化や電子署名に対応
http:
//www.trustss.co.jp/pdf/
電子証明書とCryptoAPI
5.1 電子証明書とCryptoAPI
5.2 電子証明書拡張情報とCryptoAPI
5.3 電子証明書データとCryptoAPI
5.4 暗号化データとCryptoAPI
5.1 電子証明書とCryptoAPI
5.1.1 電子証明書の準備
5.1.2 電子証明書のポインター
5.1.3 証明書情報
5.1.4 バージョンの表示
5.1.5 シリアル番号の表示
5.1.6 署名アルゴリズムの表示
5.1.7 発行者名
5.1.8 有効期間
5.1.9 サブジェクト
5.1.10 公開鍵情報
5.1.11 拡張情報
5.1.12 サンプル
5.1.13 ご質問・ご要望
5.2 電子証明書の拡張情報とCryptoAPI
5.2.1 サンプルについて
5.2.2 拡張情報のポインター
5.2.3 認証局識別子(Authority Key Identifier)
5.2.4 サブジェクト鍵識別子 (Subject Key Identifier)
5.2.5 鍵用途 (Key Usage)
5.2.6 証明書ポリシー (Certificate Polices)
5.2.7 サブジェクト代替名 (Subject Altanative Name)
5.2.8 拡張鍵用途 (Entended Key Usage)
5.2.9 サンプル
5.2.10 ご質問・ご要望
株)トラスト・ソフトウェア・システム
暗号化・電子署名・タイムスタンプ ライブラリ作成します。
お問い合わせください。
会員用ログイン
ID:
パスワード:
ログインすると、一般公開していないページを閲覧できます。