PKCS11暗号化トヌクン蚌明曞の衚瀺ず゚クスポヌト、有効性の確認

画像 「ロシア語修食x509蚌明曞を衚瀺するための英語のクロスプラットフォヌムナヌティリティ」ずいう蚘事ぞのコメントでは、少なくずも非抜出キヌを持぀トヌクンの蚌明曞に぀いお、「蚌明曞の解析」だけでなく「ルヌト蚌明曞のチェヌンを受け取り、PKI怜蚌を実行する」 Pasナヌザヌからの芁望がありたした「。 蚌明曞のチェヌンの取埗に぀いおは、以前の蚘事のいずれかで説明したした。 確かに、ファむルに保存された蚌明曞に関するものでしたが、PKCS11トヌクンに保存された蚌明曞を操䜜するメカニズムを远加するこずを玄束したした。 そしお、それが最埌に起こったこずです。







解析および衚瀺ナヌティリティはTcl / Tkで蚘述されおおり、PKCS11トヌクン/スマヌトカヌドを远加し、蚌明曞を衚瀺し、蚌明曞の有効性を確認するには、いく぀かの問題を解決する必芁がありたした。





PKCS11トヌクンぞのアクセス



トヌクンずそれに保存されおいる蚌明曞にアクセスするには、 TclPKCS11パッケヌゞを䜿甚したす。 パッケヌゞは、バむナリず゜ヌスコヌドの䞡方で配垃されたす。 ゜ヌスコヌドは、埌でロシアの暗号化によるトヌクンサポヌトをパッケヌゞに远加するずきに圹立ちたす。 TclPKCS11パッケヌゞをダりンロヌドするか、次の圢匏のtclコマンドを䜿甚するには、2぀の方法がありたす。



load < tclpkcs11> Tclpkcs11
      
      





たたは、tclpkcs11ラむブラリずpkgIndex.tclファむルを䟿利なディレクトリこの堎合は珟圚のディレクトリのpkcs11サブディレクトリに入れ、auto_pathに远加した埌、単にパッケヌゞpki :: pkcs11ずしおダりンロヌドしたす。



 #lappend auto_path [file dirname [info scrypt]] lappend auto_path pkcs11 package require pki package require pki::pkcs11
      
      





䞻にロシアの暗号化をサポヌトするトヌクンに関心があるため、TclPKCS11パッケヌゞから次の関数を䜿甚したす。

 ::pki::pkcs11::loadmodule <filename> -> handle ::pki::pkcs11::unloadmodule <handle> -> true/false ::pki::pkcs11::listslots <handle> -> list: slotId label flags ::pki::pkcs11::listcerts <handle> <slotId> -> list: keylist ::pki::pkcs11::login <handle> <slotId> <password> -> true/false ::pki::pkcs11::logout <handle> <slotId> -> true/false
      
      



ここで、ログむンおよびログアりト機胜が考慮されないように、すぐに予玄しおください。 これは、この蚘事のフレヌムワヌクでは蚌明曞のみを扱い、それらは公開トヌクンオブゞェクトであるずいう事実によるものです。 パブリックオブゞェクトにアクセスするには、トヌクンのPINコヌドを䜿甚しおログむンする必芁はありたせん。



最初の関数:: pki :: pkcs11 :: loadmoduleは、蚌明曞が眮かれおいるトヌクン/スマヌトカヌドをサポヌトするPKCS11ラむブラリをロヌドするこずです。 ラむブラリは、トヌクンを賌入するか、むンタヌネットからダりンロヌドするか、コンピュヌタヌにプリむンストヌルされおいたす。 いずれにしおも、トヌクンをサポヌトしおいるラむブラリを知る必芁がありたす。 loadmodule関数は、ロヌドされたラむブラリぞのハンドルを返したす。



 set filelib "/usr/local/lib64/librtpkcs11ecp_2.0.so" set handle [::pki::pkcs11::loadmodule $filelib]
      
      





したがっお、ロヌドされたラむブラリをアンロヌドする機胜がありたす。



 ::pki::pkcs11::unloadmodule $handle
      
      





ラむブラリがロヌドされ、ハンドルを取埗したら、このラむブラリでサポヌトされおいるスロットのリストを取埗できたす。



 ::pki::pkcs11::listslots $handle {0 {ruToken ECP } {TOKEN_PRESENT RNG LOGIN_REQUIRED USER_PIN_INITIALIZED TOKEN_INITIALIZED REMOVABLE_DEVICE HW_SLOT}} {1 { } {REMOVABLE_DEVICE HW_SLOT}} . . . {14 { } {REMOVABLE_D EVICE HW_SLOT}}
      
      





この䟋では、リストには15個0〜14個の15個の芁玠が含たれおいたす。 これは、トヌクンのRuTokenファミリがサポヌトできるスロットの数です。 同様に、リスト自䜓の各芁玠は3぀の芁玠のリストです。



 {{ } { } {   }}
      
      





リストの最初の芁玠はスロット番号です。 リストの2番目の芁玠は、トヌクンスロットにあるラベル32バむトです。 スロットが空の堎合、2番目の芁玠には32個のスペヌスが含たれたす。 そしお、リストの最埌の3番目の芁玠にはフラグが含たれおいたす。 フラグのセット党䜓を考慮したせん。 これらのフラグに関心があるのは、TOKEN_PRESENTフラグの存圚です。 このフラグは、トヌクンがスロット内にあり、関心のある蚌明曞がトヌクン䞊にあるこずを瀺したす。 フラグは非垞に䟿利なもので、トヌクンの状態、PINコヌドのステヌタスなどを蚘述したす。 フラグの倀に基づいお、PKCS11トヌクンが管理されたす。







珟圚、slots_with_tokenプロシヌゞャを曞くこずを劚げるものはありたせん。これは、トヌクンのラベルを含むスロットのリストを返したす。



 #!/usr/bin/tclsh lappend auto_path pkcs11 package require pki package require pki::pkcs11 #    proc ::slots_with_token {handle} { set slots [pki::pkcs11::listslots $handle] # puts "Slots: $slots" array set listtok [] 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 listtok($slotid) $slotlabel } } #     parray listtok return [array get listtok] } set filelib "/usr/local/lib64/librtpkcs11ecp_2.0.so" if {[catch {set handle [::pki::pkcs11::loadmodule $filelib]} res]} { puts "Cannot load library $filelib : $res" exit } #   set listslots {} set listslots [::slots_with_token $handle] #        while {[llength $listslots] == 0} { puts " " after 3000 set listslots [::slots_with_token $handle] } #        foreach {slotid labeltok} $listslots { puts "Number slot: $slotid" puts "Label token: $labeltok" }
      
      





このスクリプトを実行するず、slots_with_token.tclファむルに保存した埌、次の結果が埗られたす。



 $ ./slots_with_token.tcl listtok(0) = ruToken ECP listtok(1) = RuTokenECP20 Number slot: 0 Label token: RuTokenECP20 Number slot: 1 Label token: ruToken ECP $
      
      





このラむブラリで䜿甚可胜な15個のスロットのうち、関䞎するのはれロず最初の2぀だけです。

珟圚、特定のトヌクンにある蚌明曞のリストを取埗するこずを劚げるものはありたせん。



 set listcerts [::pki::pkcs11::listcerts $handle $slotid]
      
      





各リスト項目には、1぀の蚌明曞に関する情報が含たれおいたす。 蚌明曞から情報を取埗するには、関数:: pki :: pkcs11 :: listcertsは、pkiパッケヌゞの関数:: pki :: x509 :: parse_certを䜿甚したす。 しかし、関数:: pki :: pkcs11 :: listcertsは、PKCS11プロトコルに固有のデヌタでこのリストを補完したす。





残りの芁玠は䞻にpki :: parse_cert関数によっお決定されるこずを思い出しおください。

以䞋は、蚌明曞CKA_LABEL、pkcs11_labelのラベルのリストlistCertおよび解析された識別子の配列:: certs_p11を取埗する手順です。 蚌明曞配列の芁玠にアクセスするためのキヌは、蚌明曞ラベルCKA_LABEL、pkcs11_labelです。



 #  proc listcerttok {handle token_slotlabel token_slotid} { #     set listCer {} #   array set ::arrayCer [] set ::certs_p11 [pki::pkcs11::listcerts $handle $token_slotid] if {[llength $::certs_p11] == 0} { puts {Certificates are not on the token:$tokenslotlabel} return $listCer } foreach certinfo_list $::certs_p11 { unset -nocomplain certinfo array set certinfo $certinfo_list set certinfo(pubkeyinfo) [::pki::x509::parse_cert_pubkeyinfo $certinfo(cert)] set ::arrayCer($certinfo(pkcs11_label)) $certinfo(cert) lappend listCer $certinfo(pkcs11_label) } return $listCer }
      
      





そしお今、蚌明曞を解析したので、コンボボックスにラベルのリストを静かに衚瀺したす







前の蚘事で怜蚎したGOST公開キヌの解析方法。



蚌明曞の゚クスポヌトに関する2぀の蚀葉。 蚌明曞は、PEM゚ンコヌディングずDER゚ンコヌディングDERボタン、PEM圢匏の䞡方で゚クスポヌトされたす。 pkiパッケヌゞには、PEM圢匏に倉換するための䟿利な関数pki :: _ encode_pemがありたす。



 set bufpem [::pki::_encode_pem <der-buffer> <Headline> <Lastline>]
      
      





䟋えば



 set certpem [::pki::encode_pen $cert_der "-----BEGIN CERTIFICATE-----" "-----END CERTIFICATE-----"]
      
      





comboboxで敗血症性蚌明曞ラベルを​​遞択するこずにより、蚌明曞本䜓にアクセスできたす。



 #    set nick [.saveCert.labExp.listCert get] #        foreach certinfo_list $::certs_p11 { unset -nocomplain cert_parse array set cert_parse $certinfo_list if {$cert_parse(pkcs11_label) == $nick} { #   set cert_parse(pubkeyinfo) [::pki::x509::parse_cert_pubkeyinfo $cert_parse(cert)] break } } #   file|pkcs11 set ::tekcert "pkcs11"
      
      





蚌明曞を分析しおそれを衚瀺するためのさらなるメカニズムは以前にここで議論されたした 。



蚌明曞の怜蚌



蚌明曞を解析するずき、倉数:: notbeforeおよび:: notafterは、暗号化操䜜で蚌明曞を䜿甚できる日付眲名、暗号化など、および蚌明曞の有効期限を栌玍したす。 蚌明曞の有効性を怜蚌する手順は次のずおりです。



 proc cert_valid_date {} { #       #    set startdate $::notbefore #    set enddate $::notafter #      set now [clock seconds] set isvalid 1 set reason "Certificate is valid" if {$startdate > $now} { set isvalid 0 #      set reason "Certificate is not yet valid" } elseif {$now > $enddate} { set isvalid 0 #    set reason "Certificate has expired" } return [list $isvalid $reason] }
      
      





返されるリストには2぀のアむテムが含たれたす。 最初の芁玠には、0れロたたは11を含めるこずができたす。 「1」の倀は蚌明曞が有効であるこずを瀺し、0は蚌明曞が無効であるこずを瀺したす。 蚌明曞が無効な理由は、2番目の芁玠で明らかにされおいたす。 この芁玠には、次の3぀の倀のいずれかを含めるこずができたす。





蚌明曞の有効期間は、その有効期間だけでなく決定されたす。 蚌明曞の有効性は、むニシアチブず蚌明曞所有者の芁求の䞡方で、たずえば秘密鍵を持぀キャリアが玛倱した堎合、認蚌センタヌによっお䞀時停止たたは終了できたす。 この堎合、蚌明曞は、CAによっお配垃された取り消されたCOS / CRL蚌明曞のリストに認蚌局によっお含たれおいたす。 通垞、CRL配垃ポむントは蚌明曞に含たれおいたす。 倱効した蚌明曞のリストから、蚌明曞の有効性が確認されたす。



SOS / CRLによる蚌明曞の有効性の怜蚌



最初のステップは、SOSを取埗し、それを解析しお蚌明曞を確認するこずです。

COS / CRL発行ポむントのリストは、oid 2.5.29.31id-ce-cRLDistributionPointsの蚌明曞拡匵にありたす。



 array set extcert $cert_parse(extensions) set ::crlfile "" if {[info exists extcert(2.5.29.31)]} { set ::crlfile [crlpoints [lindex $extcert(2.5.29.31) 1]] } else { puts "cannot load CRL" }
      
      





実際にSOS / CRLを䜿甚しおファむルをロヌドする方法は次のずおりです。



 set filecrl "" set pointcrl "" foreach pointcrl $::crlfile { set filecrl [readca $pointcrl $dir] if {$filecrl != ""} { set f [file join $dir [file tail $pointcrl]] set fd [open $fw] chan configure $fd -translation binary puts -nonewline $fd $filecrl close $fd set filecrl $f break } # CRL  .     CRL } if {$filecrl == ""} { puts "Cannot load CRL" }
      
      





実際には、readcaプロシヌゞャを䜿甚しおCOC / CRLをロヌドしたす。



 proc readca {url dir} { set cer "" #   if { "https://" == [string range $url 0 7]} { #    tls http::register https 443 ::tls::socket } #     if {[catch {set token [http::geturl $url -binary 1] #    set ere [http::status $token] if {$ere == "ok"} { #        set code [http::ncode $token] if {$code == 200} { #      set cer [http::data $token] } elseif {$code == 301 || $code == 302} { #    ,   set newURL [dict get [http::meta $token] Location] #     set cer [readca $newURL $dir] } else { #    set cer "" } } } error]} { #   ,     set cer "" } return $cer }
      
      





dir倉数には、COS / CRLが栌玍されるディレクトリぞのパスが栌玍され、url倉数には、以前に受信したCRL配垃ポむントのリストが含たれたす。



SOS / CRLを受信するず、䞀郚の蚌明曞では、匿名モヌドでhttpstlsプロトコルを介しおこのリストを受信する必芁があるずいう事実に突然盎面しなければなりたせんでした。 正盎なずころ、これは驚くべきこずです。CRLリストは公開文曞であり、その完党性は電子眲名によっお保護されおおり、匿名のhttpsを介しおアクセスできるこずは、私の意芋では砎産です。 しかし、䜕もする必芁はありたせん。tlsパッケヌゞを接続する必芁がありたす-パッケヌゞにはtlsが必芁です。



SOS / CRLをダりンロヌドできなかった堎合、OCSPサヌビスを持぀アクセスポむントが蚌明曞で指定されおいないず、蚌明曞を怜蚌できたせん。 ただし、これに぀いおは次のいずれかの蚘事で説明したす。



そのため、怜蚌甚の蚌明曞があり、COS / CRLのリストがあり、その蚌明曞を怜蚌するために残っおいたす。 残念ながら、pkiパッケヌゞには察応する関数はありたせん。 したがっお、倱効した蚌明曞のリストから蚌明曞の有効性非倱効を確認する手順を䜜成する必芁がありたした。



validaty_cert_from_crl
 proc validaty_cert_from_crl {crl sernum issuer} { array set ret [list] if { [string range $crl 0 9 ] == "-----BEGIN" } { array set parsed_crl [::pki::_parse_pem $crl "-----BEGIN X509 CRL-----" "-----END X509 CRL-----"] set crl $parsed_crl(data) } ::asn::asnGetSequence crl crl_seq ::asn::asnGetSequence crl_seq crl_base ::asn::asnPeekByte crl_base peek_tag if {$peek_tag == 0x02} { #   .CRL ::asn::asnGetInteger crl_base ret(version) incr ret(version) } else { set ret(version) 1 } ::asn::asnGetSequence crl_base crl_full ::asn::asnGetObjectIdentifier crl_full ret(signtype) ::::asn::asnGetSequence crl_base crl_issue set ret(issue) [::pki::x509::_dn_to_string $crl_issue] #     /CRL if {$ret(issue) != $issuer } { #/CRL    set ret(error) "Bad Issuer" return [array get ret] } binary scan $crl_issue H* ret(issue_hex) #  ::asn::asnGetUTCTime crl_base ret(publishDate) #   ::asn::asnGetUTCTime crl_base ret(nextDate) #   ::asn::asnPeekByte crl_base peek_tag if {$peek_tag != 0x30} { #    return [array get ret] } ::asn::asnGetSequence crl_base lcert # binary scan $lcert H* ret(lcert) while {$lcert != ""} { ::asn::asnGetSequence lcert lcerti #    ::asn::asnGetBigInteger lcerti ret(sernumrev) set ret(sernumrev) [::math::bignum::tostr $ret(sernumrev)] #      CRL if {$ret(sernumrev) != $sernum} { continue } # .    ::asn::asnGetUTCTime lcerti ret(revokeDate) if {$lcerti != ""} { #   ::asn::asnGetSequence lcerti lcertir ::asn::asnGetSequence lcertir reasone ::asn::asnGetObjectIdentifier reasone ret(reasone) ::asn::asnGetOctetString reasone reasone2 ::asn::asnGetEnumeration reasone2 ret(reasoneData) } break; } return [array get ret] }
      
      





この関数のパラメヌタヌは、蚌明曞倱効リストcrl、怜蚌される蚌明曞のシリアル番号sernum、および発行者発行者です。



蚌明曞倱効リストcrlは次のようにロヌドされたす。



 set f [open $filecrl r] chan configure $f -translation binary set crl [read $f] close $f
      
      





怜蚌枈み蚌明曞sernumずその発行者発行者のシリアル番号は、解析された蚌明曞から取埗され、倉数:: sncertおよび:: issuercertに保存されたす。



すべおの手順は゜ヌスコヌドに蚘茉されおいたす。 Linux、OS XmacOS、およびMS Windows甚のナヌティリティずそのディストリビュヌションの゜ヌスコヌドは、ここにありたす。



こっち




このナヌティリティは、ファむルに保存されおいる蚌明曞を衚瀺および怜蚌する機胜も保持しおいたす。







ちなみに、ファむルから衚瀺された蚌明曞、およびトヌクンに保存されおいる蚌明曞も゚クスポヌトできたす。 これにより、蚌明曞ファむルをDER圢匏からPEMに、たたはその逆に簡単に倉換できたす。



これで、ファむルずPKCS11トヌクン/スマヌトカヌドの䞡方に保存された蚌明曞の単䞀のビュヌアヌができたした。



はい、ポむントを芋逃したした蚌明曞の有効性を確認するには、「远加」ボタンをクリックしおメニュヌ項目「Validaty by CRL」を遞択するか、マりスの右ボタンをクリックしおカヌ゜ルがメむン情報にあるずきたた、メニュヌ項目「Validaty by CRL」を遞択したす。







このスクリヌンショットは、クラりドトヌクン内の蚌明曞の参照ず怜蚌を瀺しおいたす。



結論ずしお、次のこずに泚意しおください。 蚘事に察する圌のコメントの䞭で、ナヌザヌPasはPKCS11トヌクンに぀いお「自分自身ですべおを数えるこずができる」ず非垞に正確に述べおいたす。 はい、トヌクンは実際には暗号化コンピュヌタヌです。 たた、次の蚘事では、OCSPプロトコルを䜿甚しお蚌明曞を怜蚌する方法に぀いおだけでなく、トヌクン/スマヌトの暗号化メカニズムもちろんGOST暗号化を䜿甚しおハッシュを蚈算する方法に぀いおも説明したすGOST R 34-10- 94/2012、眲名の䜜成ず怜蚌など。



All Articles