Dans l'
article précédent , le module pyp11 a été présenté, écrit en C et prenant en charge les jetons PKCS # 11 avec la cryptographie russe. Cet article examinera la classe Token, ce qui simplifiera l'utilisation des fonctionnalités du module
pyp11 dans les scripts écrits en Python. Notez que la classe token, écrite en TclOO et utilisée dans l'utilitaire cryptoarmpkcs , a
été prise comme un prototype de cette classe
:
Prototype de classe de jeton
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 classe Token, comme toute classe en Python , comprend un constructeur, des méthodes et un destructeur. Le constructeur et le destructeur sont les mêmes méthodes, uniquement avec des noms prédéfinis. Le constructeur est nommé __init__ et le destructeur est nommé __del__. Les déclarations de constructeur et de destructeur peuvent être omises. Et dans la classe Token, nous omettons la déclaration du destructeur, mais le constructeur sera nécessaire. Le constructeur instanciera la classe Token pour un jeton spécifique avec des attributs spécifiques.
Constructeur de classe de jetons
Ainsi, le constructeur de la classe Token ressemble à ceci:
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
# ()
Les paramètres du constructeur (de la méthode __init__) sont (en plus du self obligatoire) le handle de la bibliothèque de jetons (handlelp11), le numéro d'emplacement (slottoken) dans lequel le jeton doit être situé, et le numéro de série du jeton ( numéro de série).
Pour obtenir le descripteur de la bibliothèque pkcs # 11, les numéros d'emplacement et les informations sur les jetons qu'ils contiennent, vous pouvez utiliser le script suivant:
#!/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 tout est clair avec la bibliothèque et l'emplacement, la question peut se poser avec le numéro de série du jeton - pourquoi ce paramètre est nécessaire et pourquoi exactement, mais, par exemple, pas l'étiquette du jeton. Faisons une réservation tout de suite indiquant que c'est fondamental pour les jetons récupérables, lorsqu'un attaquant remplace (ou accidentellement) un jeton dans l'emplacement par un autre jeton. De plus, différentes instances du jeton peuvent avoir les mêmes étiquettes. Et enfin, le jeton n'a peut-être pas encore été initialisé ou le propriétaire le réinitialisera, en particulier, changera l'étiquette du jeton. En théorie, même un numéro de série ne garantit pas son identité; il est optimal de prendre en compte toutes les informations sur un token (numéro de série, modèle, fabricant). C'est la tâche du constructeur de stocker les arguments du jeton dans les variables de l'instance créée de la classe:
...
# handle PKCS#11
self.handle = handlelp11
#
self.slotid = slottoken
#
self.sn = serialnum
...
La méthode tokinfo () définie dans cette classe vérifie la présence du jeton spécifié dans l'emplacement spécifié .
La méthode tokinfo renvoie deux valeurs (voir ci-dessus dans le constructeur):
#
ret, stat = self.tokinfo()
La première variable (ret) contient le résultat de l'exécution de la méthode et la seconde (stat) contient des informations sur la fin de l'exécution de la méthode. Si la deuxième variable est vide, la méthode tokinfo a réussi. Si la deuxième variable n'est pas vide, la méthode s'est terminée par une erreur. Les informations d'erreur seront dans cette variable. Lorsqu'une erreur est rencontrée lors de l'exécution de la méthode self.tokinfo, le constructeur l'écrit dans la variable returncode:
#
ret, stat = self.tokinfo()
#
if (stat != ''):
# returncode
self.returncode = stat
return
Après avoir créé un objet (instance de classe), vous devez vérifier la valeur de la variable returncode pour vous assurer que l'objet pour le jeton spécifié a été créé:
#!/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 une erreur est détectée lors de la création d'un objet, il est conseillé de détruire cet objet:
del < >
II. Architecture de méthode dans la classe Token
Le principe principal lors de l'écriture de méthodes était que la gestion des exceptions était à l'intérieur des méthodes et que les informations sur les exceptions (erreurs) étaient renvoyées sous forme de texte. Sur cette base, toutes les méthodes renvoient deux valeurs: le résultat réel de l'exécution et des informations sur l'erreur. S'il n'y a pas d'erreur, la deuxième valeur est vide. Nous l'avons déjà vu en utilisant la méthode tokinfo dans le constructeur. Et voici le code de la méthode tokinfo elle-même:
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)
Une description complète de la classe Token peut être trouvée ici.
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)
Considérons l'utilisation de la fonctionnalité du module pyp11 et d'opérateurs similaires utilisant la classe Token.
Dans ce dernier cas, il sera également nécessaire de créer l'objet token:
< > = Token(< >, < >, < >)
if (< >.returncode != ''):
print(' :')
#
print(< >.returncode)
#
del < >
quit()
Commençons par initialiser le token:
try:
ret = pyp11.inittoken (< >, < >, <SO-PIN>, < >)
except:
#
e = sys.exc_info()[1]
e1 = e.args[0]
print (e1)
quit()
Le code similaire lors de l'utilisation de la classe Token ressemble à ceci (identificateur d'objet t1):
ret, stat = t1.inittoken(<SO-PIN>, < >)
#
if (stat != ''):
print(' :')
#
print(stat)
quit()
Ensuite, nous donnerons simplement la correspondance entre les principaux opérateurs du module pyp11 et les méthodes de la classe Token sans gérer les exceptions et les erreurs:
<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. Construction et installation du module pyp11 avec la classe Token
Construire et installer le module pyp11 avec la classe Token n'est pas différent de celui décrit dans la première partie.
Alors, téléchargez l' archive et décompressez-la. Nous allons dans le dossier PythonPKCS11 et exécutons la commande d'installation:
python3 setup.py install
Après avoir installé le module, allez dans le dossier tests et exécutez des tests pour le module pyp11.
Pour tester la classe Token, accédez au dossier test / classtoken.
Pour connecter le module pyp11 et la classe Token aux scripts, ajoutez simplement les opérateurs suivants:
import pyp11
from Token import Token
IV. Conclusion
Dans un proche avenir, la troisième partie de l'article devrait apparaître, qui vous dira comment ajouter la prise en charge de la cryptographie russe au projet PyKCS11 .
PS je veux dire merci svyatikov pour avoir aidé à tester le projet sur la plate-forme Windows.