فائدة عبر منصة الإنجليزية لعرض شهادات المؤهلين الروسية X509

الصورة اليوم ، أصبح استخدام الشهادات الرقمية X509 v.3 شائعًا. يستخدمهم المزيد والمزيد من الأشخاص للوصول إلى موقع ويب خدمة الدولة ، دائرة الضرائب الفيدرالية ، المزايدة الإلكترونية ، إلخ. والمزيد والمزيد من الناس يريدون أن يعرفوا ما هو موجود في هذه الشهادة التي تسمى "الصدر". وإذا كانت الشهادة تماثلية لجواز السفر ، فكيف يمكن قراءتها / عرضها. نعم ، في أنظمة التشغيل هناك العديد من الأدوات المساعدة للعرض. لكنهم سوف يقدمون القليل للمواطن العادي. خذ على سبيل المثال ، الأداة المساعدة gcr-viewer ، والتي ، في الواقع ، هي الأداة القياسية للعرض في أنظمة Linux ، وبالتالي في أنظمة التشغيل المحلية :



المشاهد القياسية


الأداة جيدة الصنع ومريحة. بشكل عام ، يُقصد به أن يكون أداة مساعدة عامة لعرض الملفات التي تحتوي على بيانات بتنسيقات تشفير مختلفة (شهادات ، طلبات ، توقيعات إلكترونية / PKCS # 7 ، حاويات محمية PKCS # 12 ، إلخ). ولكن ، لسوء الحظ ، تم تصميمه للتشفير الغربي ولا يأخذ في الاعتبار المساعدات التي يتم إدخالها في بلدك. وإذا نظرت إلى لقطة الشاشة ، فعندما يتم عرض المعلومات حول صاحب الشهادة ، تظهر أحرف غير مفهومة. على اليسار هي oid s ، وعلى اليمين في النموذج السادس عشر ، الهيكل asn1 بقيمه. في هذه الحالة ، هذه هي OGRN (1.2.643.100.1) و SNILS (1.2.643.100.3) و TIN (1.2.643.3.131.1.1). وهذه هي الطريقة التي يجب على المواطن العادي التأكد من أن هذه هي بياناته. لا تعتقد أن هذا موجود فقط على نظام Linux ، بل هو ميزة شائعة لأي عارض شهادات. وإذا نظرت إلى أبعد من ذلك ، يصبح كل شيء غير مفهوم:



تظهر بعض الملحقات والمعرفات والقيم. في هذه الحالة ، يخفي oid om 1.2.643.100.111 اسم شهادة حماية معلومات التشفير ، والتي استخدمها المستخدم لإنشاء زوج المفاتيح ، والمفتاح الخاص الذي استخدم منه لتوقيع طلب الشهادة ، والمفتاح العام الذي توجد منه الشهادة:



وهنا ، يفهم القليل من قبل صاحب الشهادة. إنه لا يفهم حتى الخوارزمية المستخدمة لإنشاء المفتاح ، إما GOST R 34.10-2001 ، أو GOST R 34.10-2012 وبأي طول مفتاح.

يمكنك الاستمرار في إعطاء أمثلة. على سبيل المثال ، إذا كانت صلاحية الشهادة واضحة ، فأين المفتاح؟

هناك سؤالان آخران يرغب أصحاب الشهادات في الحصول على إجابة لهما: أين يمكنني الحصول على سلسلة شهادات الجذر (أو حتى الحصول على أفضل منها فقط) وسؤال مماثل في قائمة الشهادات الملغاة.

وأخيرًا ، أرغب في الحصول على أداة مساعدة عالمية تأخذ في الاعتبار ميزات PKI / PKI الروسية ، والتي تعد بالفعل منصة مشتركة وتعمل على أنظمة تشغيل محلية وغير محلية . ما لتطوير؟ بالطبع في لغة البرمجة النصية ، إذا كان ذلك فقط بسبب طبيعتها عبر منصة.

ثم تذكرت أن لغة النص البرمجي الجميلة Tcl (لغة أوامر الأداة) قد احتفلت مؤخرًا بمرور 30 عامًا على تأسيسها . إنه لمن دواعي سروري أن البرنامج على ذلك. يحتوي على عدد كبير من الملحقات (الحزمة) التي تسمح بكل شيء تقريبًا. لذلك ، للعمل مع ASN- الهياكل هناك حزمة asn. علاوة على ذلك ، للعمل مع الشهادات (نحن مهتمون بتوزيعها في هذه الحالة) هناك حزمة pki. ولتطوير واجهة رسومية ، هناك حزمة Tk.

يمكن قول نفس الشيء عن بيتون مع تكينتر ، وعن بيرل وعن روبي. يمكن للجميع اختيار وفقا لذوقهم. نتوقف عند حفنة من Tcl / Tk.

سنستعير تصميم الرسوم للأداة من الأداة المساعدة gcr-viewer. وشرط واحد آخر.

نظرًا لأن لدى Habr إصدارًا باللغة الإنجليزية ، فقد أردت الأداة أن يكون لها واجهات مختلفة (الروسية / الإنجليزية). ولكن هذا ليس السبب الرئيسي. والأهم من ذلك ، أن المزيد والمزيد من مواطني العالم الغربي أصبحوا مواطنين في الاتحاد الروسي ، على سبيل المثال ، الممثل العالمي الشهير ديبارديو. قد يعترضون: إنه فرنسي. لكنني أيضًا مترجم عسكري من الفرنسية:



لذلك من السهل إضافة واجهة فرنسية. لكنني أعتقد أن Depardieu لا يوجد لديه مشاكل مع اللغة الإنجليزية. من ناحية أخرى ، فإن بلدنا متعدد الجنسيات وسيكون من الرائع أن يكون لدى البرنامج المحلي ونظام التشغيل المحلي عدة واجهات وطنية على الأقل.
مع التقدم قليلاً ، هذا ما جاء منه:



نحن ندعو مترجم


لذلك ، لنبدأ بـ "المترجم". في لقطة الشاشة ، يختبئ تحت العلم الوطني. الشرط الرئيسي للمترجم هو تزامن الترجمة ، أي القدرة على التحول إلى لغة أخرى في أي وقت. يتم تنفيذ وظائف المترجم في Tcl / Tk بواسطة حزمة msgcat:

package require msgcat 

لتعيين اللغة الحالية ، استخدم الأمر التالي:

 msgcat::mclocale ru 

يتم تخزين مفردات "المترجم" في ملف ru.msg على النحو التالي:

 #  msgcat::mcset      #     mcset namespace import -force msgcat::mcset #     mcset ru "Language" "" … 

ما يلي هو نص الاختبار
النصي مع المترجم:
 #!/usr/bin/wish -f #  msgcat package require msgcat #   ru msgcat::mclocale ru #  ::msgcat::mc      #     mc namespace import msgcat::mc #    [msgcat::mclocale].msg. #       . msgcat::mcload [file join [file dirname [info script]]] #  image create photo rf_32x21_f -file rf_32x21.png image create photo gb_32x21_f -file gb_32x21.png #,      label .lab -text "[mc Language]: " -relief flat -bd 0 –bg snow -anchor sw -width 10 button .but_lang -image rf_32x21_f -command ::changelang -relief flat -bd 0 pack .lab -side left -pady {2 0} pack .but_lang -side left #      proc ::changelang {} { #     #    if {[msgcat::mclocale] == "ru"} { msgcat::mclocale en .but_lang configure -image gb_32x21_f } else { msgcat::mclocale ru .but_lang configure -image rf_32x21_f } #  .lab configure -text "[mc Language]: " } 


في هذا البرنامج النصي ، يعمل الإجراء :: changelang كمترجم ، والذي يتم استدعاؤه عند الضغط على زر .but_lang مع العلم.

إذا قمت بتشغيل هذا البرنامج النصي ، فسترى بوضوح كيف يعمل المترجم:



الحصول على المفتاح العمومي


الآن وبعد أن قررنا وجود مترجم ، دعنا نواصل تحليل الشهادة. للقيام بذلك ، نحتاج إلى حزمة pki:

 package require pki). 

تم تصميم حزمة pki للعمل مع مفاتيح وشهادات خوارزمية RSA. إذا تم إنشاء الشهادة (proc :: pki :: x509 :: parse_cert) بنوع مختلف من المفتاح ، فلن نتلقى معلومات حول هذا المفتاح:

 # Handle RSA public keys by extracting N and E switch -- $ret(pubkey_algo) { "rsaEncryption" { set pubkey [binary format B* $pubkey] binary scan $pubkey H* ret(pubkey) ::asn::asnGetSequence pubkey pubkey_parts ::asn::asnGetBigInteger pubkey_parts ret(n) ::asn::asnGetBigInteger pubkey_parts ret(e) set ret(n) [::math::bignum::tostr $ret(n)] set ret(e) [::math::bignum::tostr $ret(e)] set ret(l) [expr {int([::pki::_bits $ret(n)] / 8.0000 + 0.5) * 8}] set ret(type) rsa } } 

والمثير للدهشة أن خوارزمية المفتاح العام ما زالت تُرجع (ret (pubkey_algo))
الموقف هو نفسه عند تحليل طلب الشهادة (proc :: pki :: pkcs :: parse_csr):

 # Parse public key, based on type switch -- $pubkey_type { "rsaEncryption" { set pubkey [binary format B* $pubkey] ::asn::asnGetSequence pubkey pubkey_parts ::asn::asnGetBigInteger pubkey_parts key(n) ::asn::asnGetBigInteger pubkey_parts key(e) set key(n) [::math::bignum::tostr $key(n)] set key(e) [::math::bignum::tostr $key(e)] set key(l) [expr {2**int(ceil(log([::pki::_bits $key(n)])/log(2)))}] set key(type) rsa } default { return -code error "Unsupported key type: $pubkey_type" } } 

لكنه هنا يعود حتى معلومات عن الخطأ. ولكن اليوم ، بالإضافة إلى RSA ، على سبيل المثال ، يتم استخدام مفاتيح المنحنيات الإهليلجية للاتحاد الأوروبي ، بما في ذلك GOST R 34.10-2012 (GOST R 34.10-2001 أيضًا في الوقت الحالي) ،.

ولكن يكفي بشكل افتراضي إرجاع بنية ASN للمفتاح العمومي الموجودة في الشهادة أو الطلب ، وسيعمل المستخدم نفسه على تحليل المفتاح العمومي وفقًا لنوع المفتاح. للقيام بذلك ، ما عليك سوى إضافة بنية ASN للمفتاح العام في القيم السداسية عشرية إلى القيم التي يتم إرجاعها:

 proc ::pki::x509::parse_cert {cert} { . . . ::asn::asnGetSequence cert subject ::asn::asnGetSequence cert pubkeyinfo #    ASN-  . binary scan $pubkeyinfo H* ret(pubkey_pubkeyinfo) . . . } 

كل شيء ، لا شيء آخر للقيام به. وبهذه الطريقة ، يقوم الإجراء :: pki :: x509 :: parse_cert بإرجاع معظم ملحقات الشهادة لسبب بسيط هو أنه لا يعرف كيفية تحليلها (على سبيل المثال ، topicSignTool بشهاداتنا المؤهلة) ، أي يعطي حسب تقدير المستخدم.

من ناحية أخرى ، يُرجع الإجراء :: pki :: x509 :: parse_cert إحدى نتائج شهادة tbs التي تحتوي على كافة المعلومات من الشهادة ، باستثناء توقيعها (توقيع) ونوع التوقيع (signature_algo):

 #    set fd [open «cert.pem» r] chan configure –translation binary set datacert [read $fd] close $fd #  array set cert_parse [::pki::x509::parse_cert $datacert] # tbs- set cert_tbs_hex $cert_parse(cert) 

نكتب الإجراء الخاص باستخراج معلومات المفتاح العام من شهادة tbs:

 proc ::pki::x509::parse_cert_pubkeyinfo {cert_tbs_hex} { array set ret [list] set wholething [binary format H* $cert_tbs_hex] ::asn::asnGetSequence wholething cert ::asn::asnPeekByte cert peek_tag if {$peek_tag != 0x02} { # Version number is optional, if missing assumed to be value of 0 ::asn::asnGetContext cert - asn_version ::asn::asnGetInteger asn_version ret(version) } ::asn::asnGetBigInteger cert ret(serial_number) ::asn::asnGetSequence cert data_signature_algo_seq ::asn::asnGetObjectIdentifier data_signature_algo_seq ret(data_signature_algo) ::asn::asnGetSequence cert issuer ::asn::asnGetSequence cert validity ::asn::asnGetUTCTime validity ret(notBefore) ::asn::asnGetUTCTime validity ret(notAfter) ::asn::asnGetSequence cert subject ::asn::asnGetSequence cert pubkeyinfo #    hex asn-   binary scan $pubkeyinfo H* ret(pubkeyinfo) return $ret(pubkeyinfo) } 

ولأننا مهتمون بالتشفير الروسي ، فسنكتب على الفور إجراء تحليل المفتاح العمومي GOST:

 proc parse_key_gost {pubkeyinfo_hex} { array set ret [list] set pubkeyinfo [binary format H* $pubkeyinfo_hex] ::asn::asnGetSequence pubkeyinfo pubkey_algoid ::asn::asnGetObjectIdentifier pubkey_algoid ret(pubkey_algo) #,   - if {[string first "1 2 643 " $ret(pubkey_algo)] == -1} { return [array get ret] } ::asn::asnGetBitString pubkeyinfo pubkey set pubkey [binary format B* $pubkey] #   binary scan $pubkey H* ret(pubkey) ::asn::asnGetSequence pubkey_algoid pubalgost #OID -  ::asn::asnGetObjectIdentifier pubalgost ret(paramkey) #OID -   ::asn::asnGetObjectIdentifier pubalgost ret(hashkey) #puts "ret(paramkey)=$ret(paramkey)\n" #puts "ret(hashkey)=$ret(hashkey)\n" #parray ret #  :  ,     return [array get ret] } 

نعم ، فاتني ذلك تقريبًا: بعد تحميل حزمة pki ، تحتاج إلى إضافة إلى صفيف :: pki :: oids oids التي تميز GOST وشهادة مؤهلة أو ببساطة غائبة في هذا الصفيف:

 package require pki # oid- set ::pki::oids(1.2.643.100.1) "OGRN" set ::pki::oids(1.2.643.100.5) "OGRNIP" set ::pki::oids(1.2.643.3.131.1.1) "INN" set ::pki::oids(1.2.643.100.3) "SNILS" set ::pki::oids(1.2.643.2.2.19) "GOST R 34.10-2001" set ::pki::oids(1.2.643.7.1.1.1.1) "GOST R 34.10-2012-256" set ::pki::oids(1.2.643.7.1.1.1.2) "GOST R 34.10-2012-512" set ::pki::oids(1.2.643.2.2.3) "GOST R 34.10-2001 with GOST R 34.11-94" set ::pki::oids(1.2.643.7.1.1.3.2) "GOST R 34.10-2012-256 with GOSTR 34.11-2012-256" set ::pki::oids(1.2.643.7.1.1.3.3) "GOST R 34.10-2012-512 with GOSTR 34.11-2012-512" set ::pki::oids(1.2.643.100.113.1) "KC1 Class Sign Tool" set ::pki::oids(1.2.643.100.113.2) "KC2 Class Sign Tool" . . . 

يمكنك أيضًا تجديد مفردات المترجم عن طريق الإضافة إلى ملف ru.msg:

 mcset ru "GOST R 34.10-2001" "  34.10-2001" mcset ru "GOST R 34.10-2012-256" "  34.10-2012-256" mcset ru "GOST R 34.10-2012-512" "  34.10-2012-512" mcset ru "GOST R 34.10-2001 with GOST R 34.11-94" "  34.10-2001    34.11-94" mcset ru "GOST R 34.10-2012-256 with GOSTR 34.11-2012-256" "  34.10-2012-256    34.11-2012-256" mcset ru "GOST R 34.10-2012-512 with GOSTR 34.11-2012-512" "  34.10-2012-512    34.11-2012-512" . . . 
:


سلسلة شهادة الجذر وقائمة إبطال الشهادات


لقد تمت مناقشة كيفية الحصول على سلسلة من شهادات الجذر مسبقًا. عن طريق القياس ، يتم كتابة الإجراء للحصول على قائمة شهادات COS / CRL الملغاة. يمكن العثور على الكود المصدري للأداة المساعدة وتوزيعاتها لنظامي التشغيل Linux و OS X (macOS) و MS Windows


في التعليمات البرمجية المصدر ، يمكنك العثور على جميع الإجراءات الخاصة بتحليل ملحقات الشهادة.
لمعارضي Tk (Tcl / Tk ، Python / Tkinter ، وما إلى ذلك) ، أقترح إيجاد ، كما يقولون ، 10 (عشرة) اختلافات بين الأداة المساعدة اثنين: الأداة المساعدة gcr-viewer المكتوبة بـ gtk والأداة المساعدة certViewer المطورة في Tk:



PKCS # 11 الرموز / البطاقة الذكية الشهادات


تحدثنا أعلاه عن العمل مع الشهادات (التصفح ، الحصول على سلسلة شهادات الجذر ، قوائم الشهادات الملغاة ، بصمات الأصابع بواسطة sha1 و sha256 ، إلخ) المخزنة في الملفات. ولكن لا تزال هناك شهادات مخزنة على الرموز PKCS # 11 / البطاقات الذكية. والرغبة الطبيعية ليست فقط لرؤيتهم ، ثم التصدير إلى ملف. كيفية القيام بذلك ، سوف نوضح في المقالة التالية:

Source: https://habr.com/ru/post/ar440754/


All Articles