I have a Smart Card (actually USB Token) with some certificate and keys written on it. Now I need to retrieve this certificate using python on Windows. How can it be achieved?
I had a look on pyscard
package but it seems too low-level and probably not a most simple way of doing this. But if you know that low-level answer then your help will be appreciated.
Seems like CryptAcquireContext
function from pywin32 (win32crypt) allow me to use private key from smart card for encryption purposes but I cannot get the certificate itself.
Do you have any suggestions?
Found an answer myself though. Hope it will help someone:
Usually smart card manufacturers provide a library (.so
or .dll
) implementing PKCS#11 standard.
There are several solutions which you can use to communicate with your smart card via this library. Such as: pkcs11-tool (CLI interface), PyKCS11 (python wrapper).
Here is an example how it could be achieved with PyKCS11:
from asn1crypto import x509
from PyKCS11 import *
pkcs11 = PyKCS11Lib()
pkcs11.load('<MANUFACTURER_LIBRARY_PATH>')
# get slot value via pkcs11.getSlotList(tokenPresent=False). Usually it's 0
session = pkcs11.openSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login('<SMART_CARD_PIN_CODE>')
result = []
certs = session.findObjects([(CKA_CLASS, CKO_CERTIFICATE)])
for cert in certs:
cka_value, cka_id = session.getAttributeValue(cert, [CKA_VALUE, CKA_ID])
cert_der = bytes(cka_value)
cert = x509.Certificate.load(cert_der)
result.append(cert)
print(result)
This way I was able to list certificates on smart card both on Linux and Windows