Utilitas bahasa Inggris lintas platform untuk melihat sertifikat berkualifikasi Rusia x509

gambar Saat ini, penggunaan sertifikat digital X509 v.3 sudah menjadi hal biasa. Semakin banyak orang menggunakannya untuk mengakses situs web Layanan Negara, Layanan Pajak Federal, penawaran elektronik, dll. Dan semakin banyak orang ingin tahu apa yang ada di "peti" yang disebut sertifikat ini. Dan jika sertifikat itu adalah analog dengan paspor, lalu bagaimana bisa dibaca / dilihat. Ya, dalam sistem operasi ada berbagai utilitas untuk dilihat. Tetapi mereka akan memberi sedikit kepada warga biasa. Ambil contoh utilitas gcr-viewer, yang, pada kenyataannya, adalah alat standar untuk melihat pada sistem Linux, dan karenanya dalam OS domestik :



Penampil standar


Utilitas dibuat dengan baik, nyaman. Secara umum, ini dimaksudkan sebagai utilitas universal untuk melihat file yang berisi data dalam berbagai format kriptografi (sertifikat, permintaan, tanda tangan elektronik / PKCS # 7, wadah yang dilindungi PKCS # 12, dll.). Tapi, sayangnya, ini dirancang untuk kriptografi Barat dan tidak memperhitungkan oids yang dimasukkan di negara Anda. Dan jika Anda melihat tangkapan layar, maka ketika informasi tentang pemegang sertifikat ditampilkan, karakter yang tidak dapat dipahami muncul. Di sebelah kiri adalah gambar itu sendiri, dan di sebelah kanan dalam bentuk ke-16, struktur asn1 dengan nilai-nilai mereka. Dalam hal ini, ini adalah OGRN (1.2.643.100.1), SNILS (1.2.643.100.3) dan TIN (1.2.643.3.131.1.1). Dan ini adalah bagaimana warga negara biasa harus memastikan bahwa ini adalah datanya. Jangan berpikir bahwa ini hanya di Linux, ini adalah fitur umum dari setiap penampil sertifikat. Dan jika Anda melihat lebih jauh, maka semuanya menjadi tidak dapat dipahami:



Beberapa ekstensi, pengidentifikasi, dan nilai muncul. Dalam hal ini, oid om 1.2.643.100.111 menyembunyikan nama CIPF, yang digunakan oleh pengguna untuk menghasilkan pasangan kunci, kunci privat yang darinya digunakan untuk menandatangani permintaan sertifikat, dan kunci publik yang darinya terdapat dalam sertifikat:



Dan di sini, sedikit yang dipahami oleh pemegang sertifikat. Dia bahkan tidak mengerti algoritma mana yang digunakan untuk menghasilkan kunci, baik GOST R 34.10-2001, atau GOST R 34.10-2012 dan dengan panjang kunci apa.

Anda dapat terus memberikan contoh. Misalnya, jika validitas sertifikat jelas, lalu di mana kuncinya?

Ada dua pertanyaan lagi yang ingin dijawab oleh pemegang sertifikat: di mana saya bisa mendapatkan rantai sertifikat root (atau lebih baik hanya mendapatkannya) dan pertanyaan serupa pada daftar sertifikat yang dicabut.

Dan akhirnya, saya ingin memiliki utilitas universal yang memperhitungkan fitur-fitur PKI / PKI Rusia, yang benar-benar lintas platform dan beroperasi pada OS domestik dan non- domestik . Apa yang harus dikembangkan? Tentu saja dalam bahasa scripting, jika hanya karena sifat lintas-platform mereka.

Kemudian saya ingat bahwa bahasa skrip yang indah Tcl (Tool Command Language) baru-baru ini merayakan peringatan ke - 30 . Merupakan suatu kesenangan untuk memprogramnya. Ini memiliki sejumlah besar ekstensi (paket) yang memungkinkan hampir semuanya. Jadi, untuk bekerja dengan struktur ASN ada paket ASN. Selain itu, untuk bekerja dengan sertifikat (kami tertarik untuk menguraikannya dalam kasus ini) ada paket pki. Dan untuk mengembangkan antarmuka grafis, ada paket Tk.

Semua hal yang sama dapat dikatakan tentang Pyton dengan Tkinter, dan tentang perl, dan tentang ruby. Setiap orang dapat memilih sesuai dengan selera mereka. Kami berhenti di sekelompok Tcl / Tk.

Kami akan meminjam desain grafis untuk utilitas dari utilitas gcr-viewer. Dan satu persyaratan lagi.

Karena Habr memiliki versi bahasa Inggris , saya ingin utilitas memiliki antarmuka yang berbeda (Rusia / Inggris). Tapi ini bukan alasan utama. Lebih penting lagi, semakin banyak warga dunia Barat yang menjadi warga Federasi Rusia, misalnya, aktor terkenal dunia Depardieu. Mereka mungkin keberatan: dia orang Prancis. Tetapi saya juga seorang penerjemah militer dari Prancis:



Jadi mudah untuk menambahkan antarmuka bahasa Prancis. Tetapi saya pikir Depardieu tidak memiliki masalah dengan bahasa Inggris. Di sisi lain, negara kita multinasional dan akan sangat baik jika perangkat lunak dalam negeri dan OS domestik memiliki setidaknya beberapa antarmuka nasional.
Berlari sedikit ke depan, inilah yang terjadi:



Kami mengundang penerjemah


Jadi, mari kita mulai dengan "penerjemah". Dalam tangkapan layar, dia bersembunyi di bawah bendera nasional. Persyaratan utama untuk penerjemah adalah sinkronisasi terjemahan, mis. kemampuan untuk beralih ke bahasa lain kapan saja. Fungsi penerjemah di Tcl / Tk dilakukan oleh paket msgcat:

package require msgcat 

Untuk mengatur bahasa saat ini, gunakan perintah berikut:

 msgcat::mclocale ru 

Kosakata dari "penerjemah" disimpan dalam file ru.msg sebagai berikut:

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

Berikut ini adalah teks tes
skrip dengan penerjemah:
 #!/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]: " } 


Dalam skrip ini, prosedur :: changelang bertindak sebagai penerjemah, yang dipanggil ketika tombol .but_lang dengan flag ditekan.

Jika Anda menjalankan skrip ini, Anda akan melihat dengan jelas bagaimana penerjemah bekerja:



Dapatkan kunci publik


Sekarang kami telah memutuskan seorang penerjemah, mari kita lanjutkan dengan analisis sertifikat. Untuk melakukan ini, kita memerlukan paket pki:

 package require pki). 

Paket pki dirancang untuk bekerja dengan kunci dan sertifikat algoritma RSA. Jika sertifikat (proc :: pki :: x509 :: parse_cert) dibuat dengan jenis kunci yang berbeda, maka kami tidak akan menerima informasi tentang kunci ini:

 # 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 } } 

Anehnya, algoritma kunci publik masih kembali (ret (pubkey_algo))
Situasinya sama dengan parsing permintaan sertifikat (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" } } 

Tetapi di sini ia bahkan mengembalikan informasi tentang kesalahan tersebut. Tetapi hari ini, selain RSA, misalnya, kunci pada kurva elips UE, termasuk GOST R 34.10-2012 (GOST R 34.10-2001 juga berlaku untuk saat ini), sedang digunakan.

Tetapi secara default cukup untuk mengembalikan struktur ASN dari kunci publik yang terletak pada sertifikat atau permintaan, dan pengguna itu sendiri akan menguraikan kunci publik tergantung pada jenis kunci. Untuk melakukan ini, cukup tambahkan struktur ASN kunci publik dalam nilai heksadesimal ke nilai yang dikembalikan:

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

Segalanya, tidak ada lagi yang bisa dilakukan. Dengan cara ini, prosedur :: pki :: x509 :: parse_cert mengembalikan sebagian besar ekstensi sertifikat karena alasan sederhana bahwa ia tidak tahu cara menguraikannya (misalnya, subjectSignTool dengan sertifikat terkualifikasi kami), yaitu. memberi atas kebijaksanaan pengguna.

Di sisi lain, prosedur :: pki :: x509 :: parse_cert mengembalikan salah satu hasil dari sertifikat tbs yang berisi semua informasi dari sertifikat, kecuali untuk tanda tangan (tanda tangan) dan jenis tanda tangan (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) 

Kami menulis prosedur untuk mengekstraksi informasi kunci publik dari sertifikat 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) } 

Dan karena kami tertarik pada kriptografi Rusia, kami akan segera menulis prosedur untuk menguraikan kunci publik 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] } 

Ya, saya hampir melewatkannya: setelah memuat paket pki, Anda perlu menambahkan ke array :: pki :: oids oids yang menjadi ciri GOST dan sertifikat yang memenuhi syarat atau tidak ada dalam array ini:

 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" . . . 

Anda juga dapat mengisi kembali kosakata penerjemah dengan menambahkan ke file 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" . . . 
:


Root rantai sertifikat dan daftar pencabutan sertifikat


Cara mendapatkan rantai sertifikat root sudah dibahas sebelumnya. Secara analogi, sebuah prosedur ditulis untuk mendapatkan daftar sertifikat COS / CRL yang dicabut. Kode sumber utilitas dan distribusinya untuk Linux, OS X (macOS) dan MS Windows dapat ditemukan


Di kode sumber, Anda dapat menemukan semua prosedur untuk mem-parsing ekstensi sertifikat.
Kepada penentang Tk (Tcl / Tk, Python / Tkinter, dll.), Saya sarankan untuk menemukan, seperti yang mereka katakan, 10 (sepuluh) perbedaan antara kedua utilitas: utilitas penampil gcr yang ditulis dalam gtk dan utilitas certViewer yang dikembangkan di Tk:



Sertifikat PKCS # 11 Token / Kartu Cerdas


Di atas kita berbicara tentang bekerja dengan sertifikat (menelusuri, mendapatkan rantai sertifikat root, daftar sertifikat yang dicabut, sidik jari oleh sha1 dan sha256, dll.) Yang tersimpan dalam file. Tetapi masih ada sertifikat yang disimpan di token / kartu pintar PKCS # 11. Dan keinginan alami tidak hanya untuk melihatnya, kemudian mengekspor ke file. Cara melakukan ini, kami akan jelaskan di artikel berikut:

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


All Articles