Use Smart Card to decrypt files 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:


Send the Smart Card certificate (containing the Public Key) to backend server
Backend server generates files and encrypts those by using the client Public key and Signs the file with backend private key
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.
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.