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エンコードされたバイナリー値が格納されています。
以下のコードでは、拡張情報の数を確認し、そのデータの種類(オブジェクト識別子)を表示します。
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" のフィールドです。これをもったフィールドのデータを確認します。
先頭の0x30は、SEQUENCEを示しています。次の0x16は、そのSEQUENCEの長さが16オクテットであるとしています。続く3番目のオクテットがコンテキストを特定するための情報で、その下5ビットが番号です。サンプルの結果では、その番号が0(ゼロ)ですので値は、keyIdentifierであることがわかります。次のオクテットは、その値の長さで、14バイトです。残りのデータが14オクテットですので、それ以外の情報を持っていないことがわかります。
AuthorityKeyIdentifierの詳細は、4.2.3認証局識別子を参照してください。
#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)
証明書ポリシーは、その電子証明書が発行されたときに基づいて、電子証明書が使用されてよい目的が示されています。
結果のみを表示します。
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となります。
結果のみを表示します。
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は、追加の識別情報です。
結果のみを記します。
1番目の情報は、第3オクテットからGenerarlNameのotherName情報であることがわかります。また、2つめの情報は、rfc822Nameであることがわかります。
結果のみを記します。
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をリンクする必要があります。
サンプルの商業利用および転載は禁止します。
このサンプルのコンパイルには、Crypt32.libとともに、Cryptui.libをリンクする必要があります。
サンプルの商業利用および転載は禁止します。
5.2.10 ご質問・ご要望
ご質問やご要望は、こちらからお送りください。(匿名でも可能です。)