How to read certificate from smart card via python?

6.4k views Asked by At

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?

1

There are 1 answers

2
fbjorn On BEST ANSWER

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