Im
vorherigen Artikel wurde das pyp11-Modul vorgestellt, in C geschrieben und bietet Unterstützung für PKCS # 11-Token mit russischer Kryptographie. In diesem Artikel wird die Token-Klasse behandelt, die die Verwendung der Funktionalität des pyp11- Moduls in in Python geschriebenen Skripten vereinfacht
. Beachten Sie, dass die in TclOO geschriebene und im Dienstprogramm cryptoarmpkcs verwendete
Token-Klasse als Prototyp dieser Klasse verwendet wurde
:
Prototyp der Token-Klasse
oo::class create token { variable libp11 variable handle variable infotok variable pintok variable nodet # constructor {handlelp11 labtoken slottoken} { global pass global yespas set handle $handlelp11 set slots [pki::pkcs11::listslots $handle] array set infotok [] foreach slotinfo $slots { set slotflags [lindex $slotinfo 2] if {[lsearch -exact $slotflags TOKEN_PRESENT] != -1} { if {[string first $labtoken [lindex $slotinfo 1]] != -1} { set infotok(slotlabel) [lindex $slotinfo 1] set infotok(slotid) [lindex $slotinfo 0] set infotok(slotflags) [lindex $slotinfo 2] set infotok(token) [lindex $slotinfo 3] # break } } } # if {[llength [array names infotok]] == 0 } { error "Constructor: Token not present for library : $handle" } # set nodet [dict create pkcs11_handle $handle] dict set nodet pkcs11_slotid $infotok(slotid) set tit " PIN- $infotok(slotlabel)" set xa [my read_password $tit] if {$xa == "no"} { error " PIN $infotok(slotlabel)" } set pintok $pass set pass "" set rr [my login ] if { $rr == 0 } { unset pintok error " PIN- $infotok(slotlabel)." } elseif {$rr == -1} { unset pintok error " ." } my logout } # method infoslot {} { return [array get infotok] } method listcerts {} { array set lcerts [] set certsder [pki::pkcs11::listcertsder $handle $infotok(slotid)] # foreach lc $certsder { array set derc $lc set lcerts($derc(pkcs11_label)) [list $derc(cert_der) $derc(pkcs11_id)] #parray derc } return [array get lcerts] } method read_password {tit} { global yespas global pass set tit_orig "$::labpas" if {$tit != ""} { set ::labpas "$tit" } tk busy hold ".st.fr1" tk busy hold ".st.fr3" # place .topPinPw -in .st.fr1.fr2_certs.labCert -relx 1.0 -rely 3.0 -relwidth 3.5 place .topPinPw -in .st.labMain -relx 0.35 -rely 5.0 -relwidth 0.30 set yespas "" focus .topPinPw.labFrPw.entryPw vwait yespas catch {tk busy forget ".st.fr1"} catch {tk busy forget ".st.fr3"} if {$tit != ""} { set ::labpas "$tit_orig" } place forget .topPinPw return $yespas } unexport read_password method rename {type ckaid newlab} { if {$type != "cert" && $type != "key" && $type != "all"} { error "Bad type for rename " } set uu $nodet lappend uu "pkcs11_id" lappend uu $ckaid lappend uu "pkcs11_label" lappend uu $newlab if { [my login ] == 0 } { unset uu return 0 } pki::pkcs11::rename $type $uu my logout return 1 } method changeid {type ckaid newid} { if {$type != "cert" && $type != "key" && $type != "all"} { error "Bad type for changeid " } set uu $nodet lappend uu "pkcs11_id" lappend uu $ckaid lappend uu "pkcs11_id_new" lappend uu $newid if { [my login ] == 0 } { unset uu return 0 } pki::pkcs11::rename $type $uu my logout return 1 } method delete {type ckaid} { if {$type != "cert" && $type != "key" && $type != "all" && $type != "obj"} { error "Bad type for delete" } set uu $nodet lappend uu "pkcs11_id" lappend uu $ckaid my login ::pki::pkcs11::delete $type $uu my logout return 1 } method deleteobj {hobj} { set uu $nodet lappend uu "hobj" lappend uu $hobj #tk_messageBox -title "class deleteobj" -icon info -message "hobj: $hobj\n" -detail "$uu" return [::pki::pkcs11::delete obj $uu ] } method listmechs {} { set llmech [pki::pkcs11::listmechs $handle $infotok(slotid)] return $llmech } method pubkeyinfo {cert_der_hex} { array set linfopk [pki::pkcs11::pubkeyinfo $cert_der_hex $nodet] return [array get linfopk] } method listobjects {type} { if {$type != "cert" && $type != "pubkey" && $type != "privkey" && $type != "all" && $type != "data"} { error "Bad type for listobjects " } set allobjs [::pki::pkcs11::listobjects $handle $infotok(slotid) $type] return $allobjs } method importcert {cert_der_hex cka_label} { set uu $nodet dict set uu pkcs11_label $cka_label if {[catch {set pkcs11id [pki::pkcs11::importcert $cert_der_hex $uu]} res] } { error "Cannot import this certificate:$res" # return 0 } return $pkcs11id } method login {} { set wh 1 set rl -1 while {$wh == 1} { if {[catch {set rl [pki::pkcs11::login $handle $infotok(slotid) $pintok]} res]} { if {[string first "SESSION_HANDLE_INVALID" $res] != -1} { pki::pkcs11::closesession $handle continue } elseif {[string first "TOKEN_NOT_PRESENT" $res] != -1} { set wh 0 continue } } break } if {$wh == 0} { return -1 } return $rl } method logout {} { return [pki::pkcs11::logout $handle $infotok(slotid)] } method keypair {typegost parkey} { my login set skey [pki::pkcs11::keypair $typegost $parkey $nodet] my logout return $skey } method digest {typehash source} { return [pki::pkcs11::digest $typehash $source $nodet] } method signkey {ckm digest hobj_priv} { set uu $nodet dict set uu hobj_privkey $hobj_priv my login set ss [pki::pkcs11::sign $ckm $digest $uu] my logout return $ss } method signcert {ckm digest pkcs11_id} { set uu $nodet dict set uu pkcs11_id $pkcs11_id my login set ss [pki::pkcs11::sign $ckm $digest $uu] my logout return $ss } method verify {digest signature asn1pubkey} { set uu $nodet dict set uu pubkeyinfo $asn1pubkey return [pki::pkcs11::verify $digest $signature $uu] } method tokenpresent {} { set slots [pki::pkcs11::listslots $handle] 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} { if {infotok(slotlabel) == $slotlabel && $slotid == $infotok(slotid)} { return 1 } } } return 0 } method setpin {type tpin newpin} { if {$type != "user" && $type != "so"} { return 0 } if {$type == "user"} { if {$tpin != $pintok} { return 0 } } set ret [::pki::pkcs11::setpin $handle $infotok(slotid) $type $tpin $newpin] if {$type == "user"} { if {$ret} { set pitok $newpin } } return $ret } method inituserpin {sopin upin} { set ret [::pki::pkcs11::inituserpin $handle $infotok(slotid) $sopin $upin] return $ret } method importkey {uukey} { set uu $nodet append uu " $uukey" my login if {[catch {set impkey [pki::pkcs11::importkey $uu ]} res] } { set impkey 0 } my logout return $impkey } # destructor { variable handle if {[info exists pintok]} { my login } # ::pki::pkcs11::unloadmodule $handle } }
Die Token-Klasse enthält wie jede Klasse in Python einen Konstruktor, Methoden und einen Destruktor. Konstruktor und Destruktor sind dieselben Methoden, nur mit vordefinierten Namen. Der Konstruktor heißt __init__ und der Destruktor heißt __del__. Konstruktor- und Destruktordeklarationen können weggelassen werden. In der Token-Klasse wird die Destruktordeklaration weggelassen, aber der Konstruktor wird benötigt. Der Konstruktor instanziiert die Token-Klasse für ein bestimmtes Token mit bestimmten Attributen.
I. Token-Klassenkonstruktor
Der Konstruktor der Token-Klasse sieht also folgendermaßen aus:
import sys
import pyp11
class Token:
def __init__ (self, handlelp11, slottoken, serialnum):
flags = ''
self.pyver = sys.version[0]
if (self.pyver == '2'):
print (' python3')
quit()
# handle PKCS#11
self.handle = handlelp11
#
self.slotid = slottoken
#
self.sn = serialnum
#
ret, stat = self.tokinfo()
#
if (stat != ''):
#
self.returncode = stat
return
# ()
Die Parameter des Konstruktors (der Methode __init__) sind (zusätzlich zum obligatorischen Selbst) das Handle der Token-Bibliothek (handlelp11), die Steckplatznummer (slottoken), in der sich das Token befinden soll, und die Token-Seriennummer ( Seriennummer).
Verwenden Sie das folgende Skript, um den Überblick über die pkcs # 11-Bibliothek, die Steckplatznummern und Informationen zu den darin enthaltenen Token zu erhalten:
#!/usr/bin/python3
import sys
import pyp11
from Token import Token
def listslots (handle):
slots = pyp11.listslots(aa)
i = 0
lslots = []
for v in slots:
for f in v[2]:
if (f == 'TOKEN_PRESENT'):
i = 1
lslots.append(v)
break
i += 1
return (lslots)
# Linux
#
lib = '/usr/local/lib64/libls11sw2016.so'
#
#lib = '/usr/local/lib64/libls11cloud.so'
#
#lib = '/usr/local/lib64/librtpkcs11ecp_2.0.so'
# Windows
#lib='C:\Temp\ls11sw2016.dll'
try:
# handle ( )
aa = pyp11.loadmodule(lib)
print('Handle ' + lib + ': ' + aa)
except:
print('Except load lib: ')
e = sys.exc_info()[1]
e1 = e.args[0]
#
print (e1)
quit()
#
slots = listslots(aa)
i = 0
for v in slots:
for f in v[2]:
if (f == 'TOKEN_PRESENT'):
if (i == 0):
print ('\n \n')
it = v[3]
print ('slotid=' + str(v[0]))
print ('\tFlags=' + str(v[2]))
print ('\tLabel="' + it[0].strip() + '"')
print ('\tManufacturer="' + it[1].strip() + '"')
print ('\tModel="' + it[2].strip() + '"')
print ('\tSerialNumber="' + it[3].strip() + '"')
i = 1
break
i += 1
pyp11.unloadmodule(aa)
if (i == 0):
print (' . ')
quit()
Wenn mit der Bibliothek und dem Steckplatz alles klar ist, kann sich die Frage mit der Seriennummer des Tokens stellen - warum dieser Parameter benötigt wird und warum genau, aber zum Beispiel nicht mit der Token-Bezeichnung. Machen wir gleich eine Reservierung, dass dies für abrufbare Token von grundlegender Bedeutung ist, wenn ein Angreifer (oder versehentlich) einen Token im Slot durch einen anderen Token ersetzt. Darüber hinaus können verschiedene Instanzen des Tokens dieselben Bezeichnungen haben. Und schließlich wurde das Token möglicherweise noch nicht initialisiert, oder der Eigentümer wird es neu initialisieren, insbesondere das Token-Label ändern. Theoretisch garantiert selbst eine Seriennummer nicht ihre Identität, es ist optimal, alle Informationen über ein Token (Seriennummer, Modell, Hersteller) zu berücksichtigen. Es ist die Aufgabe des Konstruktors, die Argumente des Tokens in den Variablen der erstellten Instanz der Klasse zu speichern:
...
# handle PKCS#11
self.handle = handlelp11
#
self.slotid = slottoken
#
self.sn = serialnum
...
Die in dieser Klasse definierte Methode tokinfo () prüft, ob das angegebene Token im angegebenen Steckplatz vorhanden ist .
Die tokinfo-Methode gibt zwei Werte zurück (siehe oben im Konstruktor):
#
ret, stat = self.tokinfo()
Die erste Variable (ret) enthält das Ergebnis der Methodenausführung und die zweite (stat) enthält Informationen darüber, wie die Ausführung der Methode beendet wurde. Wenn die zweite Variable leer ist, war die tokinfo-Methode erfolgreich. Wenn die zweite Variable nicht leer ist, wurde die Methode mit einem Fehler beendet. Die Fehlerinformationen befinden sich in dieser Variablen. Wenn während der Ausführung der Methode self.tokinfo ein Fehler auftritt, schreibt der Konstruktor ihn in die Rückgabecode-Variable:
#
ret, stat = self.tokinfo()
#
if (stat != ''):
# returncode
self.returncode = stat
return
Nach dem Erstellen eines Objekts (Klasseninstanz) müssen Sie den Wert der Returncode-Variablen überprüfen, um sicherzustellen, dass das Objekt für das angegebene Token erstellt wurde:
#!/usr/bin/python3
import sys
import pyp11
from Token import Token
#
#
lib = '/usr/local/lib64/librtpkcs11ecp_2.0.so'
try:
aa = pyp11.loadmodule(lib)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
print (e1)
quit()
#
sn = '9999999999999999'
slot = 110
#
t1 = Token(aa, slot, sn)
# returncode
if (t1.returncode != ''):
#
print (t1.returncode)
#
del t1
#
quit()
#
. . .
Wenn beim Erstellen eines Objekts ein Fehler festgestellt wird, empfiehlt es sich, dieses Objekt zu zerstören:
del < >
II. Methodenarchitektur in der Token-Klasse
Das Hauptprinzip beim Schreiben von Methoden war, dass sich die Ausnahmebehandlung innerhalb der Methoden befand und Informationen zu Ausnahmen (Fehlern) in Textform zurückgegeben wurden. Basierend darauf geben alle Methoden zwei Werte zurück: das tatsächliche Ausführungsergebnis und Informationen zum Fehler. Wenn keine Fehler vorliegen, ist der zweite Wert leer. Wir haben dies bereits mit der tokinfo-Methode im Konstruktor gesehen. Und hier ist der Code für die Tokinfo-Methode selbst:
def tokinfo(self):
status = ''
#
try:
slots = pyp11.listslots(self.handle)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
dd = ''
status = e1
return (dd, status)
status = ''
#
#
for v in slots:
#
if (v[0] != self.slotid):
status = " "
continue
self.returncode = ''
#
self.flags = v[2]
#
if (self.flags.count('TOKEN_PRESENT') !=0):
#
tokinf = v[3]
sn = tokinf[3].strip()
if (self.sn != sn):
status = ' =\"' + sn + '\" \"' + self.sn + '\"'
dd = ''
return (dd, status)
status = ''
break
else:
dd = ''
status = " "
return (dd, status)
tt = tokinf
dd = dict(Label=tt[0].strip())
dd.update(Manufacturer=tt[1].strip())
dd.update(Model=tt[2].strip())
dd.update(SerialNumber=tt[3].strip())
self.infotok = dd
#
return (dd, status)
Eine vollständige Beschreibung der Token-Klasse finden Sie hier.
import sys
import pyp11
class Token:
def __init__ (self, handlelp11, slottoken, serialnum):
flags = ''
self.pyver = sys.version[0]
if (self.pyver == '2'):
print (' python3')
quit()
# handle PKCS#11
self.handle = handlelp11
#
self.slotid = slottoken
#
self.sn = serialnum
#
ret, stat = self.tokinfo()
#
if (stat != ''):
#
self.returncode = stat
return
# ()
def tokinfo(self):
status = ''
#
try:
slots = pyp11.listslots(self.handle)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
dd = ''
status = e1
return (dd, status)
status = ''
#
#
for v in slots:
#
if (v[0] != self.slotid):
status = " "
continue
self.returncode = ''
#
self.flags = v[2]
#
if (self.flags.count('TOKEN_PRESENT') !=0):
#
tokinf = v[3]
sn = tokinf[3].strip()
if (self.sn != sn):
status = ' =\"' + sn + '\" \"' + self.sn + '\"'
dd = ''
return (dd, status)
status = ''
break
else:
dd = ''
status = " "
return (dd, status)
tt = tokinf
dd = dict(Label=tt[0].strip())
dd.update(Manufacturer=tt[1].strip())
dd.update(Model=tt[2].strip())
dd.update(SerialNumber=tt[3].strip())
self.infotok = dd
return (dd, status)
def listcerts(self):
try:
status = ''
lcerts = pyp11.listcerts(self.handle, self.slotid)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
lcerts = ''
status = e1
return (lcerts, status)
def listobjects(self, type1, value = '' ):
try:
status = ''
if (value == ''):
lobjs = pyp11.listobjects(self.handle, self.slotid, type1)
else:
lobjs = pyp11.listobjects(self.handle, self.slotid, type1, value)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
lobjs = ''
status = e1
return (lobjs, status)
def rename(self, type, pkcs11id, label):
try:
status = ''
dd = dict(pkcs11_id=pkcs11id, pkcs11_label=label)
ret = pyp11.rename(self.handle, self.slotid, type, dd)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
ret = ''
status = e1
return (ret, status)
def changeckaid(self, type, pkcs11id, pkcs11idnew):
try:
status = ''
dd = dict(pkcs11_id=pkcs11id, pkcs11_id_new=pkcs11idnew)
ret = pyp11.rename(self.handle, self.slotid, type, dd)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
ret = ''
status = e1
return (ret, status)
def login(self, userpin):
try:
status = ''
bb = pyp11.login (self.handle, self.slotid, userpin)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
bb = 0
status = e1
return (bb, status)
def logout(self):
try:
status = ''
bb = pyp11.logout (self.handle, self.slotid)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
bb = 0
status = e1
return (bb, status)
def keypair(self, typek, paramk, labkey):
#
gost2012_512 = ['1.2.643.7.1.2.1.2.1', '1.2.643.7.1.2.1.2.2', '1.2.643.7.1.2.1.2.3']
gost2012_256 = ['1.2.643.2.2.35.1', '1.2.643.2.2.35.2', '1.2.643.2.2.35.3', '1.2.643.2.2.36.0', '1.2.643.2.2.36.1', '1.2.643.7.1.2.1.1.1', '1.2.643.7.1.2.1.1.2', '1.2.643.7.1.2.1.1.3', '1.2.643.7.1.2.1.1.4']
gost2001 = ['1.2.643.2.2.35.1', '1.2.643.2.2.35.2', '1.2.643.2.2.35.3', '1.2.643.2.2.36.0', '1.2.643.2.2.36.1']
#
typekey = ['g12_256', 'g12_512', 'gost2001']
genkey = ''
if (typek == typekey[0]):
gost = gost2012_256
elif (typek == typekey[1]):
gost = gost2012_512
elif (typek == typekey[2]):
gost = gost2001
else:
status = ' '
return (genkey, status)
if (gost.count(paramk) == 0) :
status = ' '
return (genkey, status)
try:
# ,
status = ''
genkey = pyp11.keypair(self.handle, self.slotid, typek, paramk, labkey)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
print (e1)
#
status = e1
return (genkey, status)
def digest(self, typehash, source):
#
try:
status = ''
digest_hex = pyp11.digest (self.handle, self.slotid, typehash, source)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
#
status = e1
digest_hex = ''
return (digest_hex, status)
#
def sign(self, ckmpair, digest_hex, idorhandle):
# CKA_ID handle
try:
status = ''
sign_hex = pyp11.sign(self.handle, self.slotid, ckmpair, digest_hex, idorhandle)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
#
status = e1
sign_hex = ''
return (sign_hex, status)
#
def verify(self, digest_hex, sign_hex, pubkeyinfo):
# CKA_ID handle
try:
status = ''
verify = pyp11.verify(self.handle, self.slotid, digest_hex, sign_hex, pubkeyinfo)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
# status
verify = 0
status = e1
return (verify, status)
#
def inittoken(self, sopin, labtoken):
try:
status = ''
dd = pyp11.inittoken (self.handle, self.slotid, sopin, labtoken)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
# status
dd = 0
status = e1
return (dd, status)
# PIN-
def inituserpin(self, sopin, userpin):
try:
status = ''
dd = pyp11.inituserpin (self.handle, self.slotid, sopin, userpin)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
# status
dd = 0
status = e1
return (dd, status)
# PIN-
def changeuserpin(self, oldpin, newpin):
try:
status = ''
dd = pyp11.setpin (self.handle, self.slotid, 'user', oldpin, newpin)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
# status
dd = 0
status = e1
self.closesession ()
return (dd, status)
def closesession(self):
try:
status = ''
dd = pyp11.closesession (self.handle)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
# status
dd = 0
status = e1
return (dd, status)
def parsecert(self, cert_der_hex):
try:
status = ''
dd = pyp11.parsecert (self.handle, self.slotid, cert_der_hex)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
# status
dd = ''
status = e1
return (dd, status)
def importcert(self, cert_der_hex, labcert):
try:
status = ''
dd = pyp11.importcert (self.handle, self.slotid, cert_der_hex, labcert)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
# status
dd = ''
status = e1
return (dd, status)
def delobject(self, hobject):
try:
status = ''
hobjc = dict(hobj=hobject)
dd = pyp11.delete(self.handle, self.slotid, 'obj', hobjc)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
# status
dd = ''
status = e1
return (dd, status)
def delete(self, type, pkcs11id):
if (type == 'obj'):
dd = ''
status = 'delete for type obj use nethod delobject'
return (dd, status)
try:
status = ''
idobj = dict(pkcs11_id=pkcs11id)
dd = pyp11.delete(self.handle, self.slotid, type, idobj)
except:
e = sys.exc_info()[1]
e1 = e.args[0]
# status
dd = ''
status = e1
return (dd, status)
def listmechs(self):
try:
status = ''
dd = pyp11.listmechs (self.handle, self.slotid)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
# status
dd = ''
status = e1
return (dd, status)
Betrachten wir die Funktionalität des pyp11-Moduls und ähnlicher Operatoren unter Verwendung der Token-Klasse.
Im letzteren Fall muss auch das Token-Objekt erstellt werden:
< > = Token(< >, < >, < >)
if (< >.returncode != ''):
print(' :')
#
print(< >.returncode)
#
del < >
quit()
Beginnen wir mit der Initialisierung des Tokens:
try:
ret = pyp11.inittoken (< >, < >, <SO-PIN>, < >)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
print (e1)
quit()
Der ähnliche Code bei Verwendung der Token-Klasse sieht folgendermaßen aus (Objektkennung t1):
ret, stat = t1.inittoken(<SO-PIN>, < >)
#
if (stat != ''):
print(' :')
#
print(stat)
quit()
Als nächstes geben wir einfach die Entsprechung zwischen den Hauptoperatoren des pyp11-Moduls und den Methoden der Token-Klasse an, ohne Ausnahmen und Fehler zu behandeln:
<handle> := < pkcs11> <slot> := < > <error> := < > <ret> := < > <cert_der_hex> := < DER- HEX-> ================================================= # PIN- <ret> = pyp11.inituserpin (<handle>, <slot>, <SO-PIN>, <USER-PIN>) <ret>, <error> = < >.inituserpin (<SO-PIN>, <USER-PIN>) # USER-PIN <ret> = pyp11.setpin (<handle>, <slot>, 'user', <USER-PIN >, <USER-PIN >) <ret>, <error> = t1.changeuserpin (<USER-PIN >, <USER-PIN >) # SO-PIN <ret> = pyp11.setpin (<handle>, <slot>, 'so', <SO-PIN >, <SO-PIN >) <ret>, <error> = t1.changesopin (<SO-PIN >, <SO-PIN >) #Login <ret> = pyp11.login (<handle>, <slot>, <USER-PIN>) <ret>, <error> = t1.login (<USER-PIN>) #Logout <ret> = pyp11.logout (<handle>, <slot>) <ret>, <error> = t1.logout () # <ret> = pyp11.closesession (<handle>) <ret>, <error> = t1.closesession () # <ret> = pyp11.listcerts (<handle>, <slot>) <ret>, <error> = t1.listcerts () # <ret> = pyp11.listobjects (<handle>, <slot>, <'cert' | 'pubkey' | 'privkey' | 'data' | 'all'> [, 'value']) <ret>, <error> = t1.listobjects (<'cert' | 'pubkey' | 'privkey' | 'data' | 'all'> [, 'value']) # <ret> = pyp11.parsecert (<handle>, <slot>, <cert_der_hex>) <ret>, <error> = t1.parsecert(<cert_der_hex>) # <ret> = pyp11.importcert (<handle>, <slot>, <cert_der_hex>, < >) <ret>, <error> = t1.importcert(<cert_der_hex>, < >) # <ret> = pyp11.digest (<handle>, <slot>, < >, <>) <ret>, <error> = t1.digest(< >, <>) # <ret> = pyp11.digest (<handle>, <slot>, < >, < >, <CKA_ID | handle >) <ret>, <error> = t1.digest(< >, < >, <CKA_ID | handle >) # <ret> = pyp11.verify (<handle>, <slot>, < >, <>, <asn1- subjectpublickeyinfo hex>) <ret>, <error> = t1.verify(< >, <>, <asn1- subjectpublickeyinfo hex>) # <ret> = pyp11.keypair (<handle>, <slot>, < >, <OID >, <CKA_LABEL>) <ret>, <error> = t1.keypair(< >, <OID >, <CKA_LABEL>)
III. Erstellen und Installieren des pyp11-Moduls mit der Token-Klasse
Das Erstellen und Installieren des pyp11-Moduls mit der Token-Klasse unterscheidet sich nicht von dem im ersten Teil beschriebenen.
Laden Sie also das Archiv herunter und entpacken Sie es. Wir gehen in den PythonPKCS11-Ordner und führen den Installationsbefehl aus:
python3 setup.py install
Wechseln Sie nach der Installation des Moduls in den Testordner und führen Sie Tests für das pyp11-Modul aus.
Wechseln Sie zum Testen der Token-Klasse in den Ordner test / classtoken.
Fügen Sie einfach die folgenden Operatoren hinzu, um das pyp11-Modul und die Token-Klasse mit den Skripten zu verbinden:
import pyp11
from Token import Token
IV. Fazit
In naher Zukunft sollte der dritte Teil des Artikels erscheinen, in dem erläutert wird, wie Sie dem PyKCS11-Projekt Unterstützung für die russische Kryptographie hinzufügen können .
PS Ich möchte mich bedanken svyatikov um beim Testen des Projekts auf der Windows-Plattform zu helfen.