Using Chilkat with a .pfx allows me to sign N files in 30 minutes. However, if the certificate is located on an e-token (attached to usb port), then the same process takes approx. 6 hours. Can anything be done to speed up this process?
The problem is that the private key is physically stored on the e-token hardware. The actual signing must take place on the e-token. To clarify, a certificate contains within itself a public key, but the counterpart private key is stored elsewhere. The certificate may exist anywhere -- it is not something that needs to be protected. Thus certificates can be stored in the Windows Registry, while the associated private keys (forgetting e-tokens for the moment) are stored in something called the Windows Protected Store.
On a Windows system, a cert + private key can be installed such that the private key is non-exportable, i.e. the private key is located in the Protected Store and no software except for the specially privileged Microsoft implementations (such as CryptoAPI) are allowed to access the actual private key bytes to do the signing. Thus when Chilkat encounters a non-exportable private key, it automatically utilizes the MS CryptoAPI to do the signing. This can raise problems as the CryptoAPI may not support many features that Chilkat supports, or the CryptoAPI may be slower.
A certificate where the private key is located on an e-token presents the identical situation to Chilkat: The private key is non-exportable. Chilkat actually doesn't know anything about the e-token -- it simply calls the CryptoAPI exactly the same as for certs where the non-exportable private key is stored in the Windows Protected Store. It is the CryptoAPI that is in turn delegating the actual task of signing to a CSP (Cryptographic Service Provider), and in the case of an e-token, the CSP is that provided by the e-token vendor. (As opposed to the standard Microsoft-provided CSP's for private keys stored in the Windows Protected Store.)
In conclusion, I don't think it's possible for Chilkat to improve the situation. It must pass the bytes to be signed to the CryptoAPI method that does the signing. There's really no way around it.