Hardware based tokens are widely used in India to generate signed PDF’s like invoices and agreement. We wrote small Python code to sign the invoices automatically where token was attached to a local server.
Windows drives are widely available but rare to find linux drivers are listed https://www.e-mudhra.com/Repository/index.html
You can uncomment to get the token name print(self.pkcs11.getSlotList(tokenPresent=True))
print(self.pkcs11.getTokenInfo(1))
to get token name, for PROXKey the name "WD PROXKey"
was generated.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
#!/usr/bin/env vpython3 # *-* coding: utf-8 *-* import sys import datetime from endesive import pdf, hsm import os import sys if sys.platform == 'win32': dllpath = r'c:\windows\system32\cryptoCertum3PKCS.dll' else: dllpath = '/usr/lib/WatchData/ProxKey/lib/libwdpkcs_SignatureP11.so' import PyKCS11 as PK11 class Signer(hsm.HSM): def certificate(self): #print(self.pkcs11.getSlotList(tokenPresent=True)) #print(self.pkcs11.getTokenInfo(1)) # print(self.pkcs11.getTokenInfo(2)) # print(self.pkcs11.getTokenInfo(3)) # print(self.pkcs11.getSlotInfo(1)) self.login("WD PROXKey","12345678") # WF PROXKey is token name. keyid = [0x5e, 0x9a, 0x33, 0x44, 0x8b, 0xc3, 0xa1, 0x35, 0x33, 0xc7, 0xc2, 0x02, 0xf6, 0x9b, 0xde, 0x55, 0xfe, 0x83, 0x7b, 0xde] #keyid = [0x3f, 0xa6, 0x63, 0xdb, 0x75, 0x97, 0x5d, 0xa6, 0xb0, 0x32, 0xef, 0x2d, 0xdc, 0xc4, 0x8d, 0xe8] keyid = bytes(keyid) try: pk11objects = self.session.findObjects([(PK11.CKA_CLASS, PK11.CKO_CERTIFICATE)]) all_attributes = [ #PK11.CKA_SUBJECT, PK11.CKA_VALUE, #PK11.CKA_ISSUER, #PK11.CKA_CERTIFICATE_CATEGORY, #PK11.CKA_END_DATE, PK11.CKA_ID, ] for pk11object in pk11objects: try: attributes = self.session.getAttributeValue(pk11object, all_attributes) except PK11.PyKCS11Error as e: continue attrDict = dict(list(zip(all_attributes, attributes))) cert = bytes(attrDict[PK11.CKA_VALUE]) #if keyid == bytes(attrDict[PK11.CKA_ID]): return bytes(attrDict[PK11.CKA_ID]), cert finally: self.logout() return None, None def sign(self, keyid, data, mech): self.login("WD PROXKey","12345678") try: privKey = self.session.findObjects([(PK11.CKA_CLASS, PK11.CKO_PRIVATE_KEY)])[0] mech = getattr(PK11, 'CKM_%s_RSA_PKCS' % mech.upper()) sig = self.session.sign(privKey, data, PK11.Mechanism(mech, None)) return bytes(sig) finally: self.logout() def main(): date = datetime.datetime.utcnow() - datetime.timedelta(hours=12) date = date.strftime('%Y%m%d%H%M%S+00\'00\'') dct = { "sigflags": 3, "sigpage": 0, "sigbutton": True, "location": 'India', "signingdate": date.encode(), "reason": 'Sample sign', "signature": 'Madhurendra Sachan', "signaturebox": (0, 0, 100, 100), } clshsm = Signer(dllpath) fname = 'sample.pdf' datau = open(fname, 'rb').read() datas = pdf.cms.sign(datau, dct, None, None, [], 'sha256', clshsm, ) fname = fname.replace('.pdf', '-signed.pdf') with open(fname, 'wb') as fp: fp.write(datau) fp.write(datas) main() |
.dll/.so path for common tokens
- For Windows the file will be in Windows\SysWOW64″ or “WINDOWS\system32” or “WINNT\system32”
- For Linux machine the file will be in /usr/local/lib/ or /usr/lib/
Hardware Token Type | Library file (Windows) | Library file (Linux) |
---|---|---|
SafeSign | aetpkss1.dll | aetpkss1.so |
eMudhra | eMudhra\eMudhra CSPV1.0\wdpkcs.dll | 1. WatchData/eMudhra_3.4.3/lib/libpkcs11wrapper.so 2. WatchData/eMudhra_3.4.3/lib/libwdpkcs_eMudhra_343.so |
Trust Key | 1. TRUST KEY\TRUST KEY CSP V1.0\wdpkcs.dll 2. C:\Windows\System32\TRUSTKEYP11_ND_v34.dll | 1. WatchData/TRUSTKEY/lib/libpkcs11wrapper.so 2. WatchData/TRUSTKEY/lib/libwdpkcs_TRUSTKEY.so |
Belgium eID MiddleWare | beidpkcs11.dll | beidpkcs11.so |
Gemalto Cryptocard Token | libgtop11dotnet.dll | libgtop11dotnet.so |
EPass | eps2003csp11.dll | |
Aladdin eToken | eTPKCS11.dll | |
Safenet iKey | dkck201.dll | |
Starkey | aetpkss1.dll | |
Watchdata PROXkey | SignatureP11.dll | WatchData/ProxKey/lib/libwdpkcs_SignatureP11.so |