PKCS7ファイル構造

こんにちは



先日、たまたまp7sファイルのような不幸に遭遇し、その結果として、Cryptographic Message Syntax(CMS)に遭遇しました。 CMSデータの構造を説明する興味深い記事がハブで見つかりましたが、残念ながら、実際にCMSを明確に示すことができる例はありません。 この記事を少し補足し、p7sデジタル署名ファイルの内部を解析したいと思います。



ASN.1



暗号メッセージ構文とは何ですか? これは、暗号化を使用して受信したメッセージの構造を記述する標準です。

この規格では、data、signedData、envelopedData、signedAndEnvelopedData、digestedData、encryptedDataの6つのデータ型について説明しています。 このトピックでは、signedData型(電子署名付きのデータ)について説明します。



まず、標準のp7sファイルはASN.1構造を持っていると言う必要があります。

ASN.1は、さまざまなタイプで構成される複雑なデータ構造を記述することができる記録形式です。

x.509証明書に関する古いトピックからの短い抜粋を示します

ASN.1エンコードは、次のルールで記述されます。 最初に、データ型を特徴付けるバイトが書き込まれ、次にデータの長さに関する情報を格納する一連のバイトが書き込まれ、その後にデータ自体が続きます。



たとえば、整数INTEGER 65537をエンコードするには、 02 03 01 00 01という形式が使用されます。

ここでは、最初のバイト02がINTEGERのタイプを決定します(たとえば、完全なタイプテーブルをここで見つけることができます)。2番目のバイト03はブロックの長さを示します。 そして、後続のバイト01 00 01は、数値65537の16進表記です。



この場合、最も単純な自己署名証明書の説明には、9つのデータ型で十分です。 これらのタイプのコーディングテーブルは次のとおりです。

タイプ名 簡単な説明 DERエンコーディングの型表現
シーケンス さまざまなタイプで構成されるデータ構造を記述するために使用されます。 30
整数 整数 02
オブジェクト識別子 整数のシーケンス。 06
UTCTime 一時タイプ、年を決定するための2桁が含まれています 17
一般化された時間 拡張時間タイプ。年を示す4桁が含まれます。 18
セット さまざまなタイプのデータ構造を記述します。 31
UTF8String 文字列データについて説明します。 0C
ヌル 実際にはNULL 05
ビット列 ビットシーケンスを格納するための型。 03




ASN.1の詳細な説明は、記事「ASN.1 in simple words」に記載されています 。 最も一般的なp7sファイルから抽出できる情報を説明します。

P7Sファイル構造



CMS標準は、デジタル署名に関する情報を含むファイルの構造を記述しています。

SignedData ::= SEQUENCE { version CMSVersion, digestAlgorithms DigestAlgorithmIdentifiers, encapContentInfo EncapsulatedContentInfo, certificates [0] IMPLICIT CertificateSet OPTIONAL, crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, signerInfos SignerInfos }
      
      





標準に従って、CSM形式のデジタル署名されたファイルには、次のフィールドが含まれている必要があります。



これが実際にどのように見えるかを理解するために、テスト証明書で任意のバイトセットに署名し、SignedDataタイプのp7sファイルを生成します。

結果のファイルは、ASN.1構造になります。

最も一般的なデジタル署名されたファイル
 30 82 03 99 06 09 2A 86 48 86 F7 0D 01 07 02 A0 82 03 8A 30 82 03 86 02 01 01 31 0B 30 09 06 05 2B 0E 03 02 1A 05 00 30 27 06 09 2A 86 48 86 F7 0D 01 07 01 A0 1A 04 18 54 00 65 00 73 00 74 00 20 00 6D 00 65 00 73 00 73 00 61 00 67 00 65 00 A0 82 02 6B 30 82 02 67 30 82 01 D0 A0 03 02 01 02 02 11 00 D9 01 B8 B8 2F 74 CA 0E 8D 84 48 5A 22 65 E1 C3 30 0D 06 09 2A 86 48 86 F7 0D 01 01 05 05 00 30 21 31 10 30 0E 06 03 55 04 03 0C 07 54 65 73 74 20 43 41 31 0D 30 0B 06 03 55 04 0A 0C 04 54 65 73 74 30 1E 17 0D 31 35 30 34 32 39 31 32 33 33 32 30 5A 17 0D 31 35 30 35 30 36 31 32 33 33 32 30 5A 30 43 31 0D 30 0B 06 03 55 04 0C 0C 04 54 65 73 74 31 0D 30 0B 06 03 55 04 0B 0C 04 54 65 73 74 31 0D 30 0B 06 03 55 04 0A 0C 04 54 65 73 74 31 14 30 12 06 03 55 04 03 0C 0B 5B 54 45 53 54 5D 20 54 65 73 74 30 81 9F 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 81 8D 00 30 81 89 02 81 81 00 92 98 ED 87 B0 E9 DB 66 AB 06 D1 8E 7B 1B 17 40 10 98 81 D3 06 F3 B5 CA A7 FC D4 FF CB A2 2D 98 48 F9 1E 10 25 0F C6 1C 45 5D B7 A6 76 57 60 E7 BF BF DB 66 E0 D7 FC 1F 0B A1 99 1B EE C0 0D AA 76 EE 9A B8 C6 85 5D D5 C8 FA AF F8 FD 12 67 DE 6F 2D BE 5C 3E B1 88 1F 49 B2 90 AA DD B2 85 A6 46 BA 93 14 65 8C C5 20 5A AC 59 62 59 51 F1 7F BC 1E 7A D7 9F F8 8B 3B 48 2A 43 2B 7E 20 44 4B 02 03 01 00 01 A3 7D 30 7B 30 0B 06 03 55 1D 0F 04 04 03 02 04 F0 30 2C 06 03 55 1D 25 01 01 FF 04 22 30 20 06 08 2B 06 01 05 05 07 03 04 06 08 2B 06 01 05 05 07 03 02 06 0A 2B 06 01 04 01 82 37 0A 03 0C 30 1D 06 03 55 1D 0E 04 16 04 14 C7 05 8A 12 A4 B5 B7 3E F4 E5 87 6C 34 B9 BB 32 15 5E 96 91 30 1F 06 03 55 1D 23 04 18 30 16 80 14 6A E7 AB 14 AA E8 B4 C0 A8 9E 18 9D 81 68 B1 19 9F FB 25 B0 30 0D 06 09 2A 86 48 86 F7 0D 01 01 05 05 00 03 81 81 00 20 07 EF BF 72 C4 ED B8 8F B4 03 6A B8 F9 0E 16 84 89 7F B5 C5 0E 31 17 CF 80 9D B1 FB C1 C6 8B CF 3F 9C 34 51 76 21 55 29 30 E9 F3 B7 39 F5 4C E0 81 C1 04 70 67 C5 0C AE 07 80 B2 44 CB 18 3F 0E 68 67 BC EB AA 95 75 8F 7C 18 46 5B AD 96 30 70 CA 63 09 99 54 86 87 27 0A D6 DE 36 26 6A 85 64 53 B5 03 22 59 72 7F 3E 46 43 60 C2 AA EC 70 9E F7 0F 13 F5 D6 66 49 EC FE 7A 52 19 D1 27 40 31 81 DB 30 81 D8 02 01 01 30 36 30 21 31 10 30 0E 06 03 55 04 03 0C 07 54 65 73 74 20 43 41 31 0D 30 0B 06 03 55 04 0A 0C 04 54 65 73 74 02 11 00 D9 01 B8 B8 2F 74 CA 0E 8D 84 48 5A 22 65 E1 C3 30 09 06 05 2B 0E 03 02 1A 05 00 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 04 81 80 57 14 04 A3 2C 01 5B 61 B9 57 F0 02 95 0A 33 E0 94 75 CA 66 DE D0 90 93 8A E2 1A FE 6E 0B 39 C9 02 38 50 DE 7C 38 48 27 36 E9 7B FF 6C B4 DB B0 60 5C CD 78 78 54 52 54 99 A9 C4 2B 28 D7 BA AD 19 B2 6D 0D 43 B6 23 1B 5E DC B2 3E 70 FF B4 68 1D 1C 3B 6F D5 A4 0D 50 8F 55 45 7E 04 7D 2C C5 C3 80 3A 23 27 D2 E2 B4 1A 05 2E D1 3E 3A 1E 97 88 D9 12 AE B3 56 49 E9 34 97 EF 47 70 E1 66 9E
      
      







ASN.1パーサーを使用すると、16進コードの背後に隠れているものを簡単に把握できます。

 SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.7.2 (signedData) [0] { SEQUENCE { INTEGER 0x01 (1 decimal) SET { SEQUENCE { OBJECTIDENTIFIER 1.3.14.3.2.26 (id_sha1) NULL } } SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.7.1 (data) [0] { OCTETSTRING 540065007300740020006D00650073007300610067006500 } } [0] { SEQUENCE { SEQUENCE { [0] { INTEGER 0x02 (2 decimal) } INTEGER 0x00D901B8B82F74CA0E8D84485A2265E1C3 SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.1.5 (sha1WithRSAEncryption) NULL } SEQUENCE { SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.3 (commonName) UTF8String 'Test CA' } } SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.10 (organizationName) UTF8String 'Test' } } } SEQUENCE { UTCTime '150429123320Z' UTCTime '150506123320Z' } SEQUENCE { SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.12 (title) UTF8String 'Test' } } SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.11 (organizationalUnitName) UTF8String 'Test' } } SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.10 (organizationName) UTF8String 'Test' } } SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.3 (commonName) UTF8String '[TEST] Test' } } } SEQUENCE { SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.1.1 (rsaEncryption) NULL } BITSTRING 0x308189028181009298ED87B0E9DB66AB06D18E7B1B1740109881D306F3B5CAA7FCD4FFCBA22D9848F9 1E10250FC61C455DB7A6765760E7BFBFDB66E0D7FC1F0BA1991BEEC00DAA76EE9AB8C6855DD5C8FAAFF8FD1267D E6F2DBE5C3EB1881F49B290AADDB285A646BA9314658CC5205AAC59625951F17FBC1E7AD79FF88B3B482A432B7E20 444B0203010001 : 0 unused bit(s) } [3] { SEQUENCE { SEQUENCE { OBJECTIDENTIFIER 2.5.29.15 (keyUsage) OCTETSTRING 030204F0 } SEQUENCE { OBJECTIDENTIFIER 2.5.29.37 (extKeyUsage) BOOLEAN TRUE OCTETSTRING 302006082B0601050507030406082B06010505070302060A2B0601040182370A030C } SEQUENCE { OBJECTIDENTIFIER 2.5.29.14 (subjectKeyIdentifier) OCTETSTRING 0414C7058A12A4B5B73EF4E5876C34B9BB32155E9691 } SEQUENCE { OBJECTIDENTIFIER 2.5.29.35 (authorityKeyIdentifier) OCTETSTRING 301680146AE7AB14AAE8B4C0A89E189D8168B1199FFB25B0 } } } } SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.1.5 (sha1WithRSAEncryption) NULL } BITSTRING 0x2007EFBF72C4EDB88FB4036AB8F90E1684897FB5C50E3117CF809DB1FBC1C68BCF3F9C34517621552930E9F 3B739F54CE081C1047067C50CAE0780B244CB183F0E6867BCEBAA95758F7C18465BAD963070CA630999548687270AD6DE3 6266A856453B5032259727F3E464360C2AAEC709EF70F13F5D66649ECFE7A5219D12740 : 0 unused bit(s) } } SET { SEQUENCE { INTEGER 0x01 (1 decimal) SEQUENCE { SEQUENCE { SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.3 (commonName) UTF8String 'Test CA' } } SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.10 (organizationName) UTF8String 'Test' } } } INTEGER 0x00D901B8B82F74CA0E8D84485A2265E1C3 } SEQUENCE { OBJECTIDENTIFIER 1.3.14.3.2.26 (id_sha1) NULL } SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.1.1 (rsaEncryption) NULL } OCTETSTRING 571404A32C015B61B957F002950A33E09475CA66DED090938AE21AFE6E0B39C9023850DE7C38482736E97 BFF6CB4DBB0605CCD787854525499A9C42B28D7BAAD19B26D0D43B6231B5EDCB23E70FFB4681D1C3B6FD5A40D508F55 457E047D2CC5C3803A2327D2E2B41A052ED13E3A1E9788D912AEB35649E93497EF4770E1669E } } } } }
      
      







順番に始めましょう。 例からわかるように、p7sファイルは、標準で説明されているすべてのフィールドを含むSEQUENCEタイプの1つの大きなデータ構造を表します。

値が1.2.840.113549.1.7.2(SignedData)のOBJECTIDENTIFIERデータ型ブロックが開き、処理するオブジェクトの種類が明確になります。

その後、ブロックは次々に続きます。





上記の必須フィールドに加えて、SignedInfoブロックに追加されるsignedAttributesなどのオプションフィールドは、SignedDataタイプのオブジェクトで使用できます。 SignedAttributesは、署名されるデータのハッシュ値を計算するときに追加されるため、これらのフィールドを変更すると署名が無効になります。

SignedAttributesブロックを使用する場合、少なくとも2つのフィールドが含まれている必要があります。



SignedAttributesを使用して作成されたp7sファイルの別の例を考えてみましょう。

 SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.7.2 (signedData) [0] { SEQUENCE { INTEGER 0x01 (1 decimal) SET { SEQUENCE { OBJECTIDENTIFIER 1.3.14.3.2.26 (id_sha1) NULL } } SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.7.1 (data) [0] { OCTETSTRING 540065007300740020006D00650073007300610067006500 } } [0] { SEQUENCE { SEQUENCE { [0] { INTEGER 0x02 (2 decimal) } INTEGER 0x00D901B8B82F74CA0E8D84485A2265E1C3 SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.1.5 (sha1WithRSAEncryption) NULL } SEQUENCE { SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.3 (commonName) UTF8String 'Test CA' } } SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.10 (organizationName) UTF8String 'Test' } } } SEQUENCE { UTCTime '150429123320Z' UTCTime '150506123320Z' } SEQUENCE { SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.12 (title) UTF8String 'Test' } } SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.11 (organizationalUnitName) UTF8String 'Test' } } SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.10 (organizationName) UTF8String 'Test' } } SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.3 (commonName) UTF8String '[TEST] Test' } } } SEQUENCE { SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.1.1 (rsaEncryption) NULL } BITSTRING 0x308189028181009298ED87B0E9DB66AB06D18E7B1B1740109881D306F3B5CAA7FCD4FFCBA22D9848F91E102 50FC61C455DB7A6765760E7BFBFDB66E0D7FC1F0BA1991BEEC00DAA76EE9AB8C6855DD5C8FAAFF8FD1267DE6F2DBE5C 3EB1881F49B290AADDB285A646BA9314658CC5205AAC59625951F17FBC1E7AD79FF88B3B482A432B7E20444B0203010001 : 0 unused bit(s) } [3] { SEQUENCE { SEQUENCE { OBJECTIDENTIFIER 2.5.29.15 (keyUsage) OCTETSTRING 030204F0 } SEQUENCE { OBJECTIDENTIFIER 2.5.29.37 (extKeyUsage) BOOLEAN TRUE OCTETSTRING 302006082B0601050507030406082B06010505070302060A2B0601040182370A030C } SEQUENCE { OBJECTIDENTIFIER 2.5.29.14 (subjectKeyIdentifier) OCTETSTRING 0414C7058A12A4B5B73EF4E5876C34B9BB32155E9691 } SEQUENCE { OBJECTIDENTIFIER 2.5.29.35 (authorityKeyIdentifier) OCTETSTRING 301680146AE7AB14AAE8B4C0A89E189D8168B1199FFB25B0 } } } } SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.1.5 (sha1WithRSAEncryption) NULL } BITSTRING 0x2007EFBF72C4EDB88FB4036AB8F90E1684897FB5C50E3117CF809DB1FBC1C68BCF3F9C34517621552930E9F 3B739F54CE081C1047067C50CAE0780B244CB183F0E6867BCEBAA95758F7C18465BAD963070CA630999548687270AD6DE3 6266A856453B5032259727F3E464360C2AAEC709EF70F13F5D66649ECFE7A5219D12740 : 0 unused bit(s) } } SET { SEQUENCE { INTEGER 0x01 (1 decimal) SEQUENCE { SEQUENCE { SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.3 (commonName) UTF8String 'Test CA' } } SET { SEQUENCE { OBJECTIDENTIFIER 2.5.4.10 (organizationName) UTF8String 'Test' } } } INTEGER 0x00D901B8B82F74CA0E8D84485A2265E1C3 } SEQUENCE { OBJECTIDENTIFIER 1.3.14.3.2.26 (id_sha1) NULL } [0] { SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.9.3 (contentType) SET { OBJECTIDENTIFIER 1.2.840.113549.1.7.1 (data) } } SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.9.5 (signingTime) SET { UTCTime '150429124539Z' } } SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.9.4 (messageDigest) SET { OCTETSTRING F21FA6C3A1A5756D74B11C65B7D38F7EB9F458B5 } } } SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.1.1 (rsaEncryption) NULL } OCTETSTRING 21D1762506C25894B98E6BD3BB11566719AEBF642B7A4541494C45F181880D936ABC28774BA575C53CC 1CB9551ABA21359FD3FA9013DE4242802674A1C304B2601183EA8015840EEF0D0D0312E361088725A255A869EEC394C 826712F684E0BA22806BD14404EA1DD80601A8C1E6598F1CCF907EE2891FB58683EEEF121D2312 } } } } }
      
      





この例は、追加のブロックの存在が前の例と異なります。

 [0] { SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.9.3 (contentType) SET { OBJECTIDENTIFIER 1.2.840.113549.1.7.1 (data) } } SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.9.5 (signingTime) SET { UTCTime '150429124539Z' } } SEQUENCE { OBJECTIDENTIFIER 1.2.840.113549.1.9.4 (messageDigest) SET { OCTETSTRING F21FA6C3A1A5756D74B11C65B7D38F7EB9F458B5 } } }
      
      





SignedAttributesが含まれます。 2つの必須属性に加えて、署名時にsignedTime属性が使用され、署名時刻が保存されます。

結論



したがって、標準のp7sファイルは、電子署名と署名者の公開鍵に関する情報よりもはるかに多くなります。 これには、ASN.1形式で提示され、署名者に関する情報を取得できるいくつかの必須フィールドを持つ複雑なデータ構造が含まれています。 最終署名の計算に使用されるいくつかのオプションのフィールドと同様に。



All Articles