En el
artículo anterior , se presentó el módulo pyp11, escrito en C y que brinda soporte para tokens PKCS # 11 con criptografía rusa. Este artículo considerará la clase Token, que simplificará el uso de la funcionalidad del módulo
pyp11 en scripts escritos en Python. Tenga en cuenta que la clase de token, escrita en TclOO y utilizada en la utilidad cryptoarmpkcs ,
se tomó como un prototipo de esta clase
:
Prototipo de clase de token
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 } }
La clase Token, como cualquier clase en Python , incluye un constructor, métodos y un destructor. El constructor y el destructor son los mismos métodos, solo que con nombres predefinidos. El constructor se llama __init__ y el destructor se llama __del__. Se pueden omitir las declaraciones de constructor y destructor. Y en la clase Token, omitiremos la declaración del destructor, pero se necesitará el constructor. El constructor creará una instancia de la clase Token para un token específico con atributos específicos.
Constructor de clase de token
Entonces, el constructor de la clase Token se ve así:
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
# ()
Los parámetros del constructor (del método __init__) son (además del self obligatorio) el identificador de la biblioteca de tokens (handlelp11), el número de ranura (slottoken) en el que debe ubicarse el token y el número de serie del token ( serialnum).
Para obtener el control de la biblioteca pkcs # 11, los números de ranura e información sobre los tokens en ellos, puede usar el siguiente script:
#!/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()
Si todo está claro con la biblioteca y la ranura, entonces puede surgir la pregunta con el número de serie del token: por qué se necesita este parámetro y por qué es, pero, por ejemplo, no la etiqueta del token. Hagamos una reserva de inmediato de que esto es fundamental para los tokens recuperables, cuando un atacante (o accidentalmente) reemplaza un token en la ranura con otro token. Además, diferentes instancias del token pueden tener las mismas etiquetas. Y finalmente, es posible que el token aún no se haya inicializado o el propietario lo reinicializará, en particular, cambiará la etiqueta del token. En teoría, incluso un número de serie no garantiza su identidad, lo óptimo es tener en cuenta toda la información sobre un token (número de serie, modelo, fabricante). Es tarea del constructor almacenar los argumentos del token en las variables de la instancia creada de la clase:
...
# handle PKCS#11
self.handle = handlelp11
#
self.slotid = slottoken
#
self.sn = serialnum
...
El método tokinfo () definido en esta clase comprueba la presencia del token especificado en la ranura especificada .
El método tokinfo devuelve dos valores (ver arriba en el constructor):
#
ret, stat = self.tokinfo()
La primera variable (ret) contiene el resultado de la ejecución del método y la segunda (stat) contiene información sobre cómo terminó la ejecución del método. Si la segunda variable está vacía, entonces el método tokinfo tuvo éxito. Si la segunda variable no está vacía, el método ha finalizado con un error. La información del error estará en esta variable. Cuando se encuentra un error durante la ejecución del método self.tokinfo, el constructor lo escribe en la variable de código de retorno:
#
ret, stat = self.tokinfo()
#
if (stat != ''):
# returncode
self.returncode = stat
return
Después de crear un objeto (instancia de clase), debe verificar el valor de la variable de código de retorno para asegurarse de que se haya creado el objeto para el token especificado:
#!/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()
#
. . .
Si se detecta un error al crear un objeto, es recomendable destruir este objeto:
del < >
II. Arquitectura de método en la clase Token
El principio principal al escribir métodos era que el manejo de excepciones estaba dentro de los métodos y la información sobre las excepciones (errores) se devolvía en forma de texto. En base a esto, todos los métodos devuelven dos valores: el resultado de ejecución real y la información sobre el error. Si no hay errores, el segundo valor está vacío. Ya hemos visto esto usando el método tokinfo en el constructor. Y aquí está el código para el método tokinfo en sí:
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)
Puede encontrar una descripción completa de la clase Token aquí.
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)
Consideremos usar la funcionalidad del módulo pyp11 y operadores similares usando la clase Token.
En el último caso, también será necesario crear el objeto token:
< > = Token(< >, < >, < >)
if (< >.returncode != ''):
print(' :')
#
print(< >.returncode)
#
del < >
quit()
Comencemos por inicializar el token:
try:
ret = pyp11.inittoken (< >, < >, <SO-PIN>, < >)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
print (e1)
quit()
El código similar cuando se usa la clase Token se ve así (identificador de objeto t1):
ret, stat = t1.inittoken(<SO-PIN>, < >)
#
if (stat != ''):
print(' :')
#
print(stat)
quit()
A continuación, solo damos la correspondencia entre los principales operadores del módulo pyp11 y los métodos de la clase Token sin manejar excepciones y errores:
<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. Construyendo e instalando el módulo pyp11 con la clase Token
La construcción e instalación del módulo pyp11 con la clase Token no es diferente a la descrita en la primera parte.
Entonces, descargue el archivo y descomprímalo. Entramos en la carpeta PythonPKCS11 y ejecutamos el comando de instalación:
python3 setup.py install
Después de instalar el módulo, vaya a la carpeta de pruebas y ejecute las pruebas para el módulo pyp11.
Para probar la clase Token, vaya a la carpeta test / classtoken.
Para conectar el módulo pyp11 y la clase Token a los scripts, simplemente agregue los siguientes operadores:
import pyp11
from Token import Token
IV. Conclusión
En un futuro próximo, debería aparecer la tercera parte del artículo, que le dirá cómo agregar soporte para la criptografía rusa al proyecto PyKCS11 .
PD quiero darte las gracias svyatikov por ayudar a probar el proyecto en la plataforma Windows.