TIN、SNILS、およびPSRNを検索して、認定X.509証明書を逆アセンブルします

TIN、SNILS、およびPSRNを検索し、認定X.509証明書を逆アセンブルします 「同僚、私たちは、TIN、SNILS、およびPSRNで検索できる機能を備えた、発行済みの認定証明書の登録を保持する必要があります。 証明書パーサーと最初のレイアウトを作成するのに何日かかりますか?」-上司のこの質問で、次のフライが始まりました。



パーサーを書くことが提案されたので、タスクの複雑さとその実装のおよその時間枠を評価するために、メモリを考えて掘り下げる必要がありました。



小規模なSSL MITMモデリングプロジェクトに参加すると、この「中間者」のキーと証明書の生成を担当しました。 したがって、電子署名検証キーの認定証明書(以下、 認定証明書と呼びます )はX.509証明書であり、 最愛の ASN.1がその内部構造を記述するために使用されると想像しました。



当時、これらのINN、SNILS、OGRNが目に留まったことを覚えていませんでした。 したがって、彼は控えめな以上に答えました:「ボス、2日間、それ以下!」、数時間でタスクを完了することを望んで。



以下は、計算でどれだけミスを犯したか、および指定されたオブジェクト識別子(OID)でフィールドとその属性を抽出する機能を備えたC#でX.509証明書を解析するための既製のソリューションです。



ステップ1.予備調査と仮説検定



いいえ、真剣に、X.509証明書にSNILSがあるのは本当ですか? 検証用のサンプルを見つけます-「発行済みの認定証明書の登録」をリクエストしてYandexに問い合わせます。発行の最初のページで、OEPの国家起業家協会のCCが発行した証明書登録を見つけ、最初の証明書(番号10842の下)をダウンロードします-Komarov_Aleksey_Petrovich_2017-03-31_a2ba20c4。 cer



Komarov Alexey Petrovich:内部からの外観
-----証明書の開始-----

MIIIzjCCCH2gAwIBAgIRAJ6w9zrKuNKX5xH + FfdJYxwwCAYGKoUDAgIDMIH4MRww

GgYJKoZIhvcNAQkBFg11ZGNAbGVucmVnLnJ1MRgwFgYFKoUDZAESDTExMjQ3MDMw

MDAzMzMxGjAYBggqhQMDgQMBARIMMDA0NzAzMTI1OTU2MQswCQYDVQQGEwJSVTEs

MCoGA1UECAwjNzgg0LMu0KHQsNC90LrRgi3Qn9C10YLQtdGA0LHRg9GA0LMxJjAk

BgNVBAcMHdCh0LDQvdC60YIt0J / QtdGC0LXRgNCx0YPRgNCzMR0wGwYDVQQKDBTQ

k9Ca0KMg0JvQniAi0J7QrdCfIjEgMB4GA1UEAwwX0KPQpiDQk9Ca0KMg0JvQniDQ

ntCt0J8wHhcNMTcwMzMxMTAyODEwWhcNMTgwMzMxMTAyODEwWjCCAo4xIzAhBgkq

hkiG9w0BCQEWFGFwX2tvbWFyb3ZAbGVucmVnLnJ1MRowGAYIKoUDA4EDAQESDDAw

Nzg0MjM1NDk2NjEWMBQGBSqFA2QDEgswNzMxMTk5NjY2ODEYMBYGBSqFA2QBEg0x

MDc3ODQ3MTkyNjA5MSwwKgYDVQQMDCPQk9C70LDQstC90YvQuSDRgdC / 0LXRhtC4

0LDQu9C40YHRgjFBMD8GA1UECww40JTQtdC / 0LDRgNGC0LDQvNC10L3RgiDQu9C1

0YHQvdC + 0LPQviDQutC + 0LzQv9C70LXQutGB0LAxajBoBgNVBAoMYdCa0L7QvNC4

0YLQtdGCINC / 0L4g0L / RgNC40YDQvtC00L3Ri9C8INGA0LXRgdGD0YDRgdCw0Lwg

0JvQtdC90LjQvdCz0YDQsNC00YHQutC + 0Lkg0L7QsdC70LDRgdGC0LgxKjAoBgNV

BAkMIdGD0Lsu0KLQvtGA0LbQutC + 0LLRgdC60LDRjywg0LQuNDEmMCQGA1UEBwwd

0KHQsNC90LrRgi3Qn9C10YLQtdGA0LHRg9GA0LMxLDAqBgNVBAgMIzc4INCzLtCh

0LDQvdC60YIt0J / QtdGC0LXRgNCx0YPRgNCzMQswCQYDVQQGEwJSVTEoMCYGA1UE

Kgwf0JDQu9C10LrRgdC10Lkg0J / QtdGC0YDQvtCy0LjRhzEXMBUGA1UEBAwO0JrQ

vtC80LDRgNC + 0LIxajBoBgNVBAMMYdCa0L7QvNC40YLQtdGCINC / 0L4g0L / RgNC4

0YDQvtC00L3Ri9C8INGA0LXRgdGD0YDRgdCw0Lwg0JvQtdC90LjQvdCz0YDQsNC0

0YHQutC + 0Lkg0L7QsdC70LDRgdGC0LgwYzAcBgYqhQMCAhMwEgYHKoUDAgIkAAYH

KoUDAgIeAQNDAARA2jaQisiN ++ YQULAiW4b8Llik90VIKNPqUcEOVlrfplASb2W /

qc9giz + rP1 / VvQXAmRKPaL3dM33MExypCJOlGaOCBEUwggRBMA4GA1UdDwEB / wQE

AwIDqDAdBgNVHQ4EFgQU7SOIwRLKC8mDQV / q2KtCaTA06Q8wNQYJKwYBBAGCNxUH

BCgwJgYeKoUDAgIyAQmDx + sNh / eeXoXlhVqDn / dWgZtags1fAgEBAgEAMIIBYwYD

VR0jBIIBWjCCAVaAFNGDmDS2EE52TJ + tKf2SJRHjAFYJoYIBKaSCASUwggEhMRow

GAYIKoUDA4EDAQESDDAwNzcxMDQ3NDM3NTEYMBYGBSqFA2QBEg0xMDQ3NzAyMDI2

NzAxMR4wHAYJKoZIhvcNAQkBFg9kaXRAbWluc3Z5YXoucnUxPDA6BgNVBAkMMzEy

NTM3NSDQsy4g0JzQvtGB0LrQstCwINGD0LsuINCi0LLQtdGA0YHQutCw0Y8g0LQu

NzEsMCoGA1UECgwj0JzQuNC90LrQvtC80YHQstGP0LfRjCDQoNC + 0YHRgdC40Lgx

FTATBgNVBAcMDNCc0L7RgdC60LLQsDEcMBoGA1UECAwTNzcg0LMuINCc0L7RgdC6

0LLQsDELMAkGA1UEBhMCUlUxGzAZBgNVBAMMEtCj0KYgMSDQmNChINCT0KPQpoIR

BKgeQAWpGF6C5hHB / EETxEYwOQYDVR0lBDIwMAYIKwYBBQUHAwIGCCsGAQUFBwME

BggqhQMFARgCLAYIKoUDBQEYAgYGBiqFA2QCATBJBgkrBgEEAYI3FQoEPDA6MAoG

CCsGAQUFBwMCMAoGCCsGAQUFBwMEMAoGCCqFAwUBGAIsMAoGCCqFAwUBGAIGMAgG

BiqFA2QCATATBgNVHSAEDDAKMAgGBiqFA2RxATCCAQYGBSqFA2RwBIH8MIH5DCsi

0JrRgNC40L / RgtC + 0J / RgNC + IENTUCIgKNCy0LXRgNGB0LjRjyA0LjApDCoi0JrR

gNC40L / RgtC + 0J / QoNCeINCj0KYiINCy0LXRgNGB0LjQuCAyLjAMTtCh0LXRgNGC

0LjRhNC40LrQsNGCINGB0L7QvtGC0LLQtdGC0YHRgtCy0LjRjyDihJbQodCkLzEy

NC0zMDEwINC + 0YIgMzAuMTIuMjAxNgxO0KHQtdGA0YLQuNGE0LjQutCw0YIg0YHQ

vtC + 0YLQstC10YLRgdGC0LLQuNGPIOKEltCh0KQvMTI4LTI5ODMg0L7RgiAxOC4x

MS4yMDE2MDgGBSqFA2RvBC8MLSLQmtGA0LjQv9GC0L7Qn9GA0L4gQ1NQIiAo0LLQ

tdGA0YHQuNGPIDMuNi4xKTBWBgNVHR8ETzBNMCWgI6Ahhh9odHRwOi8vY2EubGVu

b2JsLnJ1L2UtZ292LTUuY3JsMCSgIqAghh5odHRwOi8vdWNsby5zcGIucnUvZS1n

b3YtNS5jcmwwOwYIKwYBBQUHAQEELzAtMCsGCCsGAQUFBzAChh9odHRwOi8vY2Eu

bGVub2JsLnJ1L2UtZ292LTUuY2VyMAgGBiqFAwICAwNBAEe1iKkhV4BQcDsBSAJa

kWfh5tNaPIp / jFc + HZtpmgJoGU8CpOdX3I5YAgJTx9O + Q4ylHwJl68rfCD44s0Q4

wqE =

-----証明書の終了-----



標準のWindows OSビューアを使用して証明書を開き、サブジェクトの説明で、11桁で構成されるオブジェクト識別子1.2.643.100.3の疑わしい類似文字列を見つけます。 SNILS



標準のWindows OCツールを使用して認定証明書を表示する






叙情的な余談



一般的にオブジェクト識別子(OID)とは何ですか? X.509証明書の構造の説明におけるオブジェクト識別子の使用方法- サバイバルガイド-TLS / SSLおよびSSL証明書(X.509)を参照してください。


暗号化プロバイダーのCryptoPRO CSPがインストールされた仮想マシンで証明書を開きます。これはおそらく国内仕様を知っており、推測を確認します。



インストールされた暗号化プロバイダーCryptoPro CSPで認定された証明書を表示する






したがって、タスクセットは実行可能である可能性があり、SNILSは認定された証明書に含まれています。 どうぞ



ステップ2.規制の枠組みに関する知識



当然、X.509証明書ではなく、TIN、SNILS、およびPSRNを見つけることができます。 たとえば、ブラウザのアドレスバー「https://yandex.ru/」の横にあるロックをクリックして証明書をエクスポートした場合、長いデジタルシーケンスはありません。



Yandex証明書を表示






X.509標準は、発行者および/またはサブジェクトの名前で指定できる属性のセットを制限しないことに注意してください。 この規格では、国、組織、地域、一般名など、いくつかの属性をサポートすることのみを推奨していますが、SNILSなどについて語られている言葉はありません。



関心のあるデータは、2011年4月6日付けの「電子署名に関する連邦法第63-FZ号の範囲内にある証明書に正確に含まれています。 第17条を慎重に検討し、TIN、SNILS、およびPSRNが実際に認定証明書に含まれていることを確認します。



次に、TIN値に対応するOIDと、SNILSとPSRNを確認する必要があります。 2011年12月27日のロシア連邦連邦安全保障局の命令第795号「資格のある証明書の形式の要件の承認について」に言及する規制の枠組みの見直しは、この問題に役立ちます。 注文を開き、興味のある情報を見つけます。



18.連邦法に従って使用の必要性が確立されている名前の追加属性には、以下が含まれます。



1)OGRN。

OGRN属性の値は、適格証明書(法人)の所有者のOGRNを表す13桁の文字列です。 OGRN属性タイプのオブジェクト識別子の形式は1.2.643.100.1です。OGRN属性タイプの説明は次のとおりです。OGRN :: = NUM​​ERIC STRING SIZE 13;



2)SNILS(SNILS)。

SNILS属性の値は11桁の文字列であり、認定された証明書の所有者(個人)のSNILSを表します。 SNILS属性タイプのオブジェクト識別子は1.2.643.100.3であり、SNILS属性タイプは次のように説明されます。SNILS :: = NUM​​ERIC STRING SIZE 11;



3)イン。

INN属性の値は、資格のある証明書の所有者のTINを表す12桁の文字列です。 INN属性タイプのオブジェクト識別子は1.2.643.3.131.1.1であり、INN属性タイプは次のように記述されています:INN :: = NUM​​ERIC STRING SIZE 12。


あなた自身を検証しようとすることができます-OIDを知って、それが記述するオブジェクトを見つけてください。 たとえば、OID = 1.2.643.100.3(SNILS)を使用します。 識別子の公式登録に目を向け、ツリーを「ウォーク」します。



1 - International Organization for Standardization (ISO) 1.2 - ISO Member Bodies 1.2.643 - Russian federation
      
      





値1.2.643.100はもう見つかりません。そのようなOIDは公式カタログにリストされていません。 国立登録簿へのリンクをたどり、検索を続けます。 ツリーを「下る」ことができる発見された識別子:



 1.2.643.100 ( OID' 1.2.643.100.1,  ,  OID' 1.2.643.100.3,  ) -   1.2.643.3.131 ( OID' 1.2.643.3.131.1.1,  ) -    
      
      





オブジェクト識別子の全国登録のサイトにすべての層が表示されるわけではないため、自分自身を確認することはできません。 しかし、希望は最後になります。公式ツリーオペレータ-Infotex Internet Trust OJSCに公式リクエストを送信しようとしています。 通信を引用します。



-教えてください 、OIDに対応するオブジェクト明確にすることはサイトoid.iitrust.ruで可能ですか:1.2.643.3.131.1.1、1.2.6443.100.1、1.2.6443.100.3? これらは検索に含まれていませんが、これらはTIN、PSRN、およびSNILSであると想定しています。 どうすればこれを確認できますか?



-良い一日! あなたが示したOIDは、2011年12月27日付のロシアのFSBの注文番号795によって承認されています。



サークルは閉じられており、検証が成功したと思われます。



2011年12月27日の第795号のロシア連邦連邦治安局の命令を引き続き調査し、フィールドとその属性の完成は資格のある証明書の所有者(個人または法人)に依存するという事実に注目します。 たとえば、属性commonName(共通名)の入力の説明:



名前のこの属性の値として、個人の名前、姓と後援者(存在する場合)、または法人の名前を含むテキスト文字列を使用する必要があります。 属性タイプcommonNameのオブジェクト識別子の形式は2.5.4.3です。


このケース(Komarov_Aleksey_Petrovich_2017-03-31_a2ba20c4.cer)では、commonName属性の値は「レニングラード地域の天然資源委員会」の行であるため、証明書の所有者は法人です。



法人の場合、オブジェクト識別子(すべてではなく、選択的、興味深い)の属性タイプへの次の対応を確立します。



 2.5.4.3 –    2.5.4.8 -     1.2.643.3.131.1.1 –  1.2.643.100.1 –  1.2.643.100.3 –     1.2.840.113549.1.9.1 –   
      
      





ステップ3. CでのパーサーX.509証明書の開発#



私たちはC#で開発しているので、パーサーの例はC#であり、個人的なものもホリバーもありません。



簡単にするために、次のように問題を形式化します。 指定: CER(正規エンコード規則)制限システムの修飾された証明書ファイル。 必須:証明書解析(解析)し、件名フィールド(件名)からTIN、SNILS、OGRNの値を抽出します。



最初のドラフトでは、System.Security.Cryptography.X509Certificates名前空間の機能を調べます。



 using System.IO; using System.Security.Cryptography.X509Certificates; using System.Diagnostics; namespace X509Parser { class Program { static void Main(string[] args) { string fileName = @"c:\Komarov_Aleksey_Petrovich_2017-03-31_a2ba20c4.cer"; X509Certificate cert = new X509Certificate(File.ReadAllBytes(fileName)); Debug.Print(" : {0}", cert.GetSerialNumberString()); Debug.Print("    : {0}", cert.GetExpirationDateString()); Debug.Print(": {0}", cert.Subject); } } }
      
      





出力は次のとおりです。



  : 009EB0F73ACAB8D297E711FE15F749631C     : 31.03.2018 13:28:10 : CN=     , SN=, G= , C=RU, S=78 .-, L=-, STREET="., .4", O=     , OU=  , T= , OID.1.2.643.100.1=1077847192609, OID.1.2.643.100.3=07311996668, OID.1.2.643.3.131.1.1=007842354966, E=ap_komarov@lenreg.ru
      
      





X509Certificate.Subjectプロパティは、string型の証明書のサブジェクトの名前を返します。



一見すると、単純な正規表現( )で停止して、OIDと値の型を知っている文字列から関心のある値を選択できます。 しかし、あなたは認めなければならない、そのような決定の優雅さは明らかに十分ではありません。 さらに、インストールされた暗号化プロバイダーは、OIDコードをシンボリックシンボルに置き換えることができます。これにより、コードが不必要に複雑になります。



適切なソリューションを探して、.NETクラスライブラリを注意深く調べて、さらに試行します。 件名フィールドを一連のバイトとして参照しようとすると、標準の.NETプラットフォームツールを使用して、OIDで検索できる証明書構造を表示するのがまったく不便であることが明らかになりました。



StackOverflowはヒントを提供します-サードパーティのライブラリを使用し、最も引用されているものを選択してください-BouncyCastle



ライブラリは、プロジェクトへの参照を追加することにより、ワンクリックで接続されます。 提案された抽象化レベルにより、ASN.1形式のデータを直感的に表示できます。 パーサーの位置を正しく示すために、証明書ファイルの先頭に関連する関心のある値の「オフセット」を明確にするだけです。



ASN.1エディターで証明書を開き、証明書の構造との通信を設定します。



ASN.1 Editorで認定証明書を表示する



  (0、2254)SEQUENCE-括弧で囲まれたルートシーケンス(オフセット、長さ)
	 (4、2173)シーケンス-証明書
		 (8、3)CONTEXT SPECIFIC-証明書バージョン
		 (13、17)INTEGER-シリアル番号
		 (32、8)SEQUENCE-署名アルゴリズム識別子
		 (42、248)SEQUENCE-出版社名
		 (293、30)SEQUENCE-有効期間
		 (325、654)SEQUENCE-サブジェクト名 


TIN、SNILS、およびPSRNの値が記録される「サブジェクト名」フィールドに関心があります。 図を注意深く見ると、次の結論を導き出すことができます。「サブジェクト名」フィールド(325、654)SEQUENCEは、キー/値ペアのシーケンス(SEQUENCE)で構成されるセット(SET)のシーケンス(SEQUENCE)です。



このロジックに従って、パーサーを実装します。



 using System.Diagnostics; using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.X509; namespace X509Parser { class Program { static void Main(string[] args) { //         27.12.2011 №795 string fileName = @"c:\Komarov_Aleksey_Petrovich_2017-03-31_a2ba20c4.cer"; X509CertificateParser parser = new X509CertificateParser(); X509Certificate cert = parser.ReadCertificate(File.ReadAllBytes(fileName)); Debug.Print(" : {0}", cert.SerialNumber.ToString(16).ToUpper()); Debug.Print("    : {0}", cert.NotAfter.ToString("dd.MM.yyyy")); //   subject = SEQ of SET of SEQ of {OID/value} DerSequence subject = cert.SubjectDN.ToAsn1Object() as DerSequence; foreach (Asn1Encodable setItem in subject) { DerSet subSet = setItem as DerSet; if (subSet == null) continue; //    SET -   SEQ of {OID/value} DerSequence subSeq = subSet[0] as DerSequence; foreach (Asn1Encodable subSeqItem in subSeq) { DerObjectIdentifier oid = subSeqItem as DerObjectIdentifier; if (oid == null) continue; string value = subSeq[1].ToString(); if (oid.Id.Equals("2.5.4.3")) Debug.Print("   /   : {0}", value); if (oid.Id.Equals("2.5.4.8")) Debug.Print("   : {0}", value); if (oid.Id.Equals("1.2.643.3.131.1.1")) Debug.Print(": {0}", value); if (oid.Id.Equals("1.2.643.100.1")) Debug.Print(": {0}", value); if (oid.Id.Equals("1.2.643.100.3")) Debug.Print(": {0}", value); if (oid.Id.Equals("1.2.840.113549.1.9.1")) Debug.Print(" : {0}", value); } } } } }
      
      





私たちは結論を見て同意します:



  : 9EB0F73ACAB8D297E711FE15F749631C     : 31.03.2018  : ap_komarov@lenreg.ru : 007842354966 : 07311996668 : 1077847192609    : 78 .-    /   :      
      
      





問題は解決しました。



まとめ



したがって、完了した作業をまとめると、次のようになります。



  1. 「電子署名に関する」連邦法の範囲内にあるX.509認定証明書の構造を把握しました。
  2. ロシア連邦第795号の連邦保安局により、TIN、SNILS、PSRNなどの追加属性が定義されていることがわかりました。 対応するオブジェクト識別子(OID)もここに示されています。
  3. 指定したオブジェクト識別子でフィールドとその属性を抽出する機能を備えたC#用のX.509証明書パーサーを開発しました。 BouncyCastleライブラリーにより、ソリューションがシンプルになりました。


時間の計算でエラーが発生しました-計画された数時間ではなく、一日中把握する必要がありました。 そして、さらに2日間、Habrの研究を準備します。



ご清聴ありがとうございました!



ソースのリスト






All Articles