So I'm trying to figure out the feasibility of using a Smart Card to decrypt files in an offline scenario.

I wish to sync encrypted files to a mobile phone with a Smart Card reader case. The files should only be readable when the Smart Card is in the card slot. If the user looses the phone the files will be stored in a encrypted format on disk only.

Assume that I will not be able to write any actual Smart Card apps myself and that the Smart Card is a US CAC or equivalent.

My thinking goes something like this:

  1. Send the Smart Card certificate (containing the Public Key) to backend server
  2. Backend server generates files and encrypts those by using the client Public key and Signs the file with backend private key
  3. Client receives files, verifies backend signature and then decrypts the file with the Smart Card private key

For number 3 I wonder if this is available and would it be performant for text only files?

If it is available, how does it work. Will the Smart Card take a stream of encrypted bytes and then spit out a stream of unencrypted bytes?

Any references to similar examples, code etc appreciated.

Edit: By performant I mean decryption measures with bytes/s. I saw in a talks that the cards have accelerated encryption chips but I don't really know what that implies.

Also, found some sample code from a course homepage at Radboud University. So it is possible to achieve with a custom Java Applet. I'm still wondering if there are any "standard" ways of doing this, either as a part of APDU or GlobalPlatform commands.

Crypto Applet https://www.cs.ru.nl/E.Poll/hw/samples/CryptoApplet.java

Usage from Java https://www.cs.ru.nl/E.Poll/hw/samples/CryptoTerminalSmartCardIO.java

Edit 2: So I figured out that the card supports PKCS#11 and that is probably what I should use.

I've downloaded the pkcs11-tool which works well for browsing/viewing things. I can list certificates etc. But when I try to sign something I get that the operation is unsupported (PKCS11 function C_SignFinal failed: rv = CKR_FUNCTION_NOT_SUPPORTED (0x54)).

The documentation I've found on this tool is not very good (no examples just man page) so if anyone knows how to do this properly please tell:

pkcs11-tool --module $OPENSC_LIB --sign --slot 0x2 --input-file message.txt --login --pin XXXXXX --mechanism SHA1-RSA-PKCS 

By the looks of it I would also be able to use PKCS#11 to decrypt a message. Didn't get that far yet.

  • $\begingroup$ Comments are not for extended discussion, providing semi-answers, or exchanging project ideas; this conversation has been moved to chat. $\endgroup$
    – e-sushi
    Commented Mar 29, 2016 at 16:51
  • $\begingroup$ Could you please define or explain what you mean when asking …would it be performant for text only files? Do you mean “performant” in terms of security, or speed, or resource consumption, … what exactly are you hinting at when using that word? $\endgroup$
    – e-sushi
    Commented Mar 29, 2016 at 16:56
  • $\begingroup$ @e-sushi I mean performant as in encrypting/decrypting long byte streams on the card might be slow. $\endgroup$
    – Magnus
    Commented Mar 29, 2016 at 17:54

1 Answer 1


If it is available, how does it work. Will the Smart Card take a stream of encrypted bytes and then spit out a stream of unencrypted bytes?

No, that's generally not what happens. In general smart card simply supply an RSA operation that performs raw RSA, RSA PKCS#1 or RSA OAEP decryption. The result of this operation is a relatively small amount of bytes; e.g. in the case of RSA PKCS#1 about 11 bytes less then the key size (which is the size of the modulus for RSA). If a raw RSA operation is provided then the unpadding should be performed by the off card entity.

So what is used is a hybrid cryptosystem. Such a system uses a random, symmetric data key to encrypt the plaintext. This random data key - usually an AES key - is then encrypted by the RSA public key. The encrypted data key is stored together with the ciphertext using a container format such as CMS or Open PGP.

Upon decryption the AES data key is first decrypted with the private key on the smart card. This for instance requires a PIN code to be entered to gain access to the private key. Once the data key is decrypted it can be used to decrypt the rest of the data. Using authenticated encryption (such as GCM) should of course be preferred.

So the smart card only "accelerates" the private key operation. I put that between quotes as in general a mainstream CPU will be much faster than the speed of the cryptographic co-processor and the communication overhead provided by the card. The AES operations are performed off-card, and they bear the brunt of the work for any files above, say, a few KiB.

  • $\begingroup$ Yes I agree that using a Hybrid Crypto system is a good way to go. I've actually already considered a variant of this, but I wanted to keep it simple for the question and also find out if it was nessecary. I still need to decrypt the symmetric key I have encrypted with the card public key, so my latest update is still something I need to investigate. But that is a different question. $\endgroup$
    – Magnus
    Commented Mar 29, 2016 at 21:59
  • $\begingroup$ Note that specific keys may have different key usages. You need to use a key with the right key usage to sign or to decrypt. $\endgroup$
    – Maarten Bodewes
    Commented Mar 29, 2016 at 22:30
  • $\begingroup$ Thanks. Yes I am aware of this. The ones available support signatures. I will troubleshoot a little bit more and see if I can find some examples to proceed. $\endgroup$
    – Magnus
    Commented Mar 29, 2016 at 23:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.