
في التعليقات على المقال "استخدام PKCS # 11 آليات التشفير في لغات البرمجة النصية" ،
كتب قارئ
kovserg :
"نحن نتطلع إلى مقال مع وظيفة توقيع وثيقة وإضافة طابع زمني."
في وقت سابق ، كتب مشارك آخر في
pas Habr أنه سيكون من الرائع بالنسبة لرموز PKCS # 11 ، "التي يمكن لأي شخص حسابها" (بمعنى عمليات التشفير في المقام الأول لإنشاء المفاتيح وإنشاء المفاتيح الإلكترونية والتحقق منها) ، والتخلص من جميع أنواع الطبقات البينية أداة واحدة يمكنها ، باستخدام آليات الرمز نفسه ، أن تشكل طلب شهادة وتوقيع مستندات ، والتحقق من توقيع المستندات ، والتحقق من توقيع الشهادات وصلاحيتها.
التعرف على الأداة
نتيجة لذلك ، نقدم الأداة المساعدة إلى محكمة المستخدمين

القوة الدافعة لهذه الأداة هي
رمز التشفير
PKCS # 11 مع دعم للتشفير الروسي على الأقل GOST R 34.10-2012. إذا كنت تنوي استخدام
الخدمات العامة ، وما إلى ذلك ، فلا تزال بحاجة إلى شراء رمز مميز اجتاز اختبارات معتمدة في نظام شهادات FSB في روسيا. إذا كانت هذه هي إدارة المستندات الإلكترونية الداخلية الخاصة بك ، فهذا بالطبع ، حسب تقديرك. يمكن أن تكون الرموز PKCS # 11 مختلفة: البرامج ، الأجهزة ، أو حتى
السحابة . تتم كتابة الأداة المساعدة في لغة البرمجة النصية
Tcl / Tk . عند شراء رمز PKCS # 11 ، لا تنسى أن تحصل أو تسأل عن المكان الذي يمكنك تنزيل المكتبات من خلال الرمز المميز الذي تم شراؤه لأنظمة تشغيل مختلفة. المكتبات عادة ما تكون متاحة بحرية. تستخدم الأداة المساعدة حزمة
TclPKCS11 للوصول إلى
ميزات التشفير وغيرها من
الميزات المميزة . تبدأ الأداة المساعدة باختيار مكتبة تدعم الرموز الخاصة بك. لاحظ أنه يمكن لمكتبات المكتبات العمل في وقت واحد مع عدة رموز (combobox "select token / البطاقة الذكية"):

قد ينشأ السؤال ، لكن ماذا أفعل إذا لم يتم تهيئة الرمز المميز أو كنت بحاجة إلى تغيير رموز PIN ، وما إلى ذلك؟ الجواب بسيط - استخدم أداة تكوين الرمز المميز
p11conf .
لتحديث قائمة الرموز (تعطيل الرمز المميز ، أضف واحدة جديدة) فقط انقر
بواسطة أيقونة

الموجود على يمين combobox "اختر رمز مميز / البطاقة الذكية"
يحتوي combox "Certificate" على تسميات لجميع الشهادات المخزنة على الرمز المميز (الحالي) المحدد:

إذا قمت بالنقر فوق الرمز

الموجود على يمين شهادة combobox ، تظهر نافذة تحتوي على محتويات الشهادة:

إذا قمت بالنقر فوق الزر "حفظ / حفظ" في نافذة العرض ، فسيتم حفظ محتويات الشهادة التي تم تحليلها بتنسيق النص في الملف الذي حددته.
لعرض معلومات حول الرمز المميز الحالي ، يمكنك النقر فوق الزر "6. معلومات على الرمز المميز" أو نقل المؤشر إلى التسمية المميزة:

لمعرفة آليات التشفير التي يدعمها الرمز المميز الحالي ، ما عليك سوى النقر فوق الزر "5. قائمة الآليات":

إنشاء طلب شهادة
نمر إلى الوظائف الرئيسية للأداة. وأول وظيفة من هذا القبيل هي إنشاء طلب شهادة (زر "3. طلب شهادة"):

تظهر الرسالة "الرمز لا يدعم المفاتيح ..." إذا كان الرمز المميز المحدد لا يدعم إنشاء هذا النوع من المفاتيح. في هذه الحالة ، تحتاج إلى تحديد نوع مختلف من المفتاح أو رمز مميز آخر. في هذا المثال ، يمكنك استخدام الرمز المميز RuToken ECP 2.0 (انظر لقطة الشاشة الثانية). Combobox "حامل الشهادة" يسمح لك بتحديد من سيملك الشهادة: فرد أو كيان قانوني أو رجل أعمال فردي. بناءً على ذلك ، سيتم تشكيل الحقول المراد ملؤها على الصفحات التالية.
حقل مهم هنا هو حقل "اسم CIPF". إنه جزء لا يتجزأ من الشهادة المؤهلة ويشير إلى كيفية قيام نظام حماية معلومات التشفير بإنشاء زوج المفاتيح. يمكنك معرفة اسم شهادة حماية معلومات التشفير في نموذج المنتج أو في وقت شراء الرمز المميز. هل يتزامن حقل الكتابة في المعلومات الرمزية مع اسم نظام حماية معلومات التشفير؟ لذلك من الأفضل رؤية النموذج. انقر فوق "التالي" واملأ الحقول المطلوبة:

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

بعد النقر على زر "التالي" ، سيُطلب منك النظر مرة أخرى في ما أدخلته وتأكيد قرارك عن طريق الضغط على مفتاح "إنهاء":

وإذا قمت بالنقر فوق الزر "إنهاء" ، فسيتم إنشاء زوج مفاتيح على الرمز المميز الخاص بك ، وسيتم إنشاء طلب وتوقيعه:

وهل يمكنك التأكد من إنشاء المفاتيح وتخزينها على الرمز المميز؟ نعم. نضغط على الزر "7. كائنات رمزية" ، وأدخل رمز PIN للوصول إلى الرمز المميز وابحث عن كائنات SKO_PRIVATE_KEY و CKO_PUBLIV_KEY ، التي تتطابق تسمياتها مع حقل "COMMON NANE" (CN) الذي قمت بملئه عند إنشاء طلب الشهادة. في مثالنا ، كان "الله العظيم":

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

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

بعد أن يدخل التطبيق قاعدة بيانات المرجع المصدق (CA) ، يعتبرها المسؤول المعتمد ويرفضها أو يوافق عليها:

بعد الموافقة على الطلب ، يحدد مقدم الطلب ، مع الشخص المفوض من CA ، أغراض استخدام الشهادة:

وبعد ذلك ، لا شيء يمنع إصدار الشهادة:

بعد إصدار الشهادة ، يقوم موظف CA بتصدير الشهادة الصادرة إلى محرك الأقراص المحمول الخاص بـ Hon. Habr:

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

يمكننا أيضًا التحقق من صحة الشهادة (ولكن لم يكن لدينا وقت لإبطالها بعد) أو صحة توقيعها عن طريق تحديد العملية المناسبة:

شهادة أداة التحقق من توقيع الشهادة#!/usr/bin/env tclsh package require pki load ./tclpkcs11.so Tclpkcs11 # PKCS#11 #set pkcs11_module "/usr/local/lib64/librtpkcs11ecp_2.0.so" set pkcs11_module "/usr/local/lib64/libls11sw2016.so" puts "Connect the Token and press Enter" gets stdin yes set handle [pki::pkcs11::loadmodule $pkcs11_module] set slots [pki::pkcs11::listslots $handle] set i 0 foreach slotinfo $slots { set slotid [lindex $slotinfo 0] set slotlabel [lindex $slotinfo 1] set slotflags [lindex $slotinfo 2] if {[lsearch -exact $slotflags TOKEN_PRESENT] != -1} { set token_slotlabel $slotlabel set token_slotid $slotid # incr i break } } if {$i == 0} { puts " . ." exit } # PEM DER proc ::cert_to_der {data} { if {[string first "-----BEGIN CERTIFICATE-----" $data] != -1} { set data [string map {"\r\n" "\n"} $data] } array set parsed_cert [::pki::_parse_pem $data "-----BEGIN CERTIFICATE-----" "-----END CERTIFICATE-----"] if {[string range $parsed_cert(data) 0 0 ] == "0" } { # DER- "0" == 0x30 set asnblock $parsed_cert(data) } else { set asnblock "" } return $asnblock } proc usage {use error} { puts "Copyright(C) Orlov Vladimir (http://museum.lissi-crypto.ru/) 2019" if {$use == 1} { puts $error puts "Usage:\nverify_cert_with_pkcs11 <file with certificate> \[<file with CA certificate>\]\n" } } set countcert [llength $argv] if { $countcert < 1 || $countcert > 2 } { usage 1 "Bad usage!" exit } set file [lindex $argv 0] if {![file exists $file]} { usage 1 "File $file not exist" exit } # cert_user puts "Loading user certificate: $file" set fd [open $file] chan configure $fd -translation binary set cert_user [read $fd] close $fd if {$cert_user == "" } { usage 1 "Bad file with certificate user: $file" exit } set cert_user [cert_to_der $cert_user] if {$cert_user == ""} { puts "User certificate bad" exit } catch {array set cert_parse [::pki::x509::parse_cert $cert_user]} if {![info exists cert_parse]} { puts "User certificate bad" exit } #parray cert_parse if {$countcert == 1} { if {$cert_parse(issuer) != $cert_parse(subject)} { puts "Bad usage: not self signed certificate" } else { set cert_CA $cert_user } } else { set fileca [lindex $argv 1] if {![file exists $fileca]} { usage 1 "File $fileca not exist" exit } # cert_CA puts "Loading CA certificate: $fileca" set fd [open $fileca] chan configure $fd -translation binary set cert_CA [read $fd] close $fd if {$cert_CA == "" } { usage 1 "Bad file with certificate CA=$fileca" exit } set cert_CA [cert_to_der $cert_CA] if {$cert_CA == ""} { puts "CA certificate bad" exit } } foreach slotinfo $slots { set slotid [lindex $slotinfo 0] set slotlabel [lindex $slotinfo 1] set slotflags [lindex $slotinfo 2] if {[lsearch -exact $slotflags TOKEN_PRESENT] != -1} { set token_slotlabel $slotlabel set token_slotid $slotid } } # catch {array set cert_parse_CA [::pki::x509::parse_cert $cert_CA]} if {![info exists cert_parse_CA]} { puts "CA certificate bad" exit } # if {$cert_parse(issuer) != $cert_parse_CA(subject)} { puts "Bad issuer" exit } set aa [dict create pkcs11_handle $handle pkcs11_slotid $token_slotid] set tbs_cert [binary format H* $cert_parse(cert)] catch {set signature_algo_number [::pki::_oid_name_to_number $cert_parse(signature_algo)]} if {![info exists signature_algo_number]} { set signature_algo_number $cert_parse(signature_algo) } switch -- $signature_algo_number { "1.2.643.2.2.3" - "1 2 643 2 2 3" { # "GOST R 34.10-2001 with GOST R 34.11-94" set digest_algo "gostr3411" } "1.2.643.7.1.1.3.2" - "1 2 643 7 1 1 3 2" { # "GOST R 34.10-2012-256 with GOSTR 34.11-2012-256" set digest_algo "stribog256" } "1.2.643.7.1.1.3.3" - "1 2 643 7 1 1 3 3" { # "GOST R 34.10-2012-512 with GOSTR 34.11-2012-512" set digest_algo "stribog512" } default { puts " :$signature_algo_number" exit } } # tbs-!!!! set digest_hex [pki::pkcs11::digest $digest_algo $tbs_cert $aa] # asn- # binary scan $cert_CA H* cert_CA_hex array set infopk [pki::pkcs11::pubkeyinfo $cert_CA_hex [list pkcs11_handle $handle pkcs11_slotid $token_slotid]] set lpk [dict create pkcs11_handle $handle pkcs11_slotid $token_slotid] # pybkeyinfo lappend lpk "pubkeyinfo" lappend lpk $infopk(pubkeyinfo) array set lpkar $lpk puts "Enter PIN user for you token \"$token_slotlabel\":" gets stdin password if { [pki::pkcs11::login $handle $token_slotid $password] == 0 } { puts "Bad PIN" exit } if {[catch {set verify [pki::pkcs11::verify $digest_hex $cert_parse(signature) $lpk]} res] } { puts " =$res" exit } if {$verify != 1} { puts "BAD SIGNATURE=$verify" } else { puts "SIGNATURE OK=$verify" }
لكننا مهتمون الآن بعملية استيراد الشهادة المستلمة إلى الرمز المميز لدينا. حدد العملية "استيراد شهادة الرمز المميز" وانقر فوق الزر "إجراء عملية". سوف تتحقق الأداة من التوقيع الإلكتروني للشهادة. للقيام بذلك ، ستتم مطالبتك بإدخال رمز PIN للرمز المميز. وإذا سارت الأمور على ما يرام ، فسيتم استيراد الشهادة إلى الرمز المميز:

يمكن رؤية التسمية (اللقب) للشهادة في قائمة الشهادات:

هذه هي شهادةنا الشخصية ، وهي شهادة يوجد بها زوج رئيسي. وإذا نظرت إلى قائمة الكائنات الموجودة على الرمز المميز مرة أخرى ، فسنجد ثلاثة كائنات لها التصنيف "Almighty Habr from UTs 12_512" ونفس CKA_ID. هذه
الكائنات الثلاثة هي الشهادة نفسها (CKO_CERTIFICATE) وعامة (CKO_PUBLIC_KEY) ومفاتيح خاصة (CKO_PRIVATE_KEY). يتم تعيين التسمية لهذا الثلاثي الكائنات على النحو التالي:
<حامل شهادة CN> من <الناشر شهادة CN>.
نعرض أدناه كيفية تغيير الملصق.
الآن بعد أن وضعنا الشهادة على الرمز المميز ، كيف يمكن الوصول إليها؟ من أجل الوصول إلى وظائف العمل مع الشهادات الموجودة على الرمز المميز ، ما عليك سوى نقل المؤشر إلى علامة "الشهادة" واضغط على زر الماوس الأيمن:

نوقع المستند الأول مع التوقيع الإلكتروني
دعنا ننتظر المقال القادم. عليك أن تنتظر بضعة أيام. ماذا سيتم النظر هناك يمكن فهمه من لقطة الشاشة:
تابع هنا .