Authentication with a MIFARE DESFire Gentle card utilizing a key saved within the Android Keystore | by Lucia Lenz | Dec, 2022


To authenticate with MIFARE DESFire Gentle playing cards a pre-shared AES-key is required. This key must be saved safely. On Android the most secure place for the secret’s within the safe {hardware} of the system utilizing the Android Keystore. The Android Keystore may be very restrictive. The secret’s imported into the keystore along with a listing, which specifies which operations are permitted. For the reason that key cannot go away the safe {hardware}, it might solely be used with algorithms obtainable contained in the keystore. These options have two difficult penalties. I’ll focus on find out how to clear up them within the following.

This text is not going to focus on any particulars about distributing AES-keys from a server to the gadgets and importing them into the Android Keystore. It is a fairly superior subject by itself. I’ll assume you have already got that mechanism in place.

MIFARE DESFire Gentle authentication and the Android Keystore problem

Allow us to recap which steps are wanted as a way to set up encrypted communication. We’re going to take a look at AuthenticateEV2First solely. Which is the default method for authentication with these sort of playing cards. Please check with the official nxp documentation if you happen to want additional particulars.

Simplified course of to begin communication in CommunicationMode.Full

The telephone proves to the cardboard that it posesses the AES-key with out exposing it and vise versa. The method consists of the next steps:

  1. The telephone initiates authentication and receives a random quantity RndB, which was encrypted by the cardboard. An AES/CBC cipher is used with the pre-shared AES-key and a set zero initialisation vector (IV).
  2. The telephone decrypts RndB and returns the proof, along with an encrypted random quantity RndA.
  3. The cardboard proves in flip that it was in a position to decrypt RndA by returning the proof along with the preliminary session information.
  4. With the preliminary session information the session keys are calculated utilizing a CMAC algorithm. All consecutive communication with the cardboard might be encrypted with these session keys, which mutate with every name.

When going via this course of with an Android Keystore key, the primary problem is that an IV set by the caller isn’t permitted by default however is required for steps 1 to three. The second problem is, that the CMAC algorithm wanted for step 4 isn’t obtainable within the Android Keystore. Let’s have a look at the 2 issues one after the opposite.

Fixing the “caller-provided IV not permitted” problem

The Android Keystore doesn’t allow setting an IV for a cipher by the caller by default. As an alternative the cipher generates its personal IV randomly to ensure identical enter doesn’t yield identical output. Subsequently making an attempt to set the zero IV for our AES/CBC cipher will end in an exception like this:

java.safety.InvalidAlgorithmParameterException: 
Caller-provided IV not permitted

That is good while you use the important thing for encryption. However when utilizing it for authentication, it’s essential that the telephone and the cardboard do the identical steps. Subsequently we are going to permit a caller offered IV for this key.

Distributing secret keys to Android and importing them into the Android Keystore is defined within the Android docs. Roughly, the AES-key is encrypted server-side with a public key created within the Android Keystore. Then the encrypted AES-key, along with its metadata, is shipped again to the system in ASN.1 format. On the system the secret’s imported into the keystore the place it’s decrypted in flip.

The ASN.1 for the important thing and its metadata seems to be like this:

For our problem the attention-grabbing half is the AuthorizationList. This property is defined in this android reference. There we additionally discover the ASN.1 description of the AuthorizationList itself:

The property which we now have to set as a way to present a customized IV is named CALLER_NONCE and is omitted within the documentation, however it’s applied within the android keymaster hal. There we be taught that it’s enumerated with 7. We additionally want the block mode, which is enumerated with 4. Right here I embrace it into the ASN.1 definition of the AuthorizationList:

Now we now have so as to add this property in our implementation that constructs the ASN.1 bytearray. We add callerNonce just for the AES-key the place it’s needed. Offering an IV for a cipher is unhealthy apply as talked about above. We solely allow it for the AES-key used for authentication. Additionally, it’s best to solely set the wanted algorithm and block mode to make sure that the secret’s not used with insecure algorithms. Right here ist the snippet:

We use Bouncy Fortress to create the bytearray. If you wish to perceive ASN.1, learn this nice article. There may be, in fact, rather more code required to create the SecureKeyWrapper, however right here we simply consider the steps required to speak with the MIFARE card. After you set the important thing properties accurately, the encrypted AES-key ought to be distributed to the gadgets and imported within the keystore as ordinary.

Fixing the “CMAC algorithm” problem

The second problem is, that there isn’t a CMAC algorithm obtainable within the Android Keystore. It’s unimaginable to make use of an Android Keystore key exterior of the Android Keystore (that is the primary cause why it’s so protected). Subsequently we cannot use e.g. Bouncy Castles CMAC implementation.

The excellent news is: the one second we’d like the AES-key is after we encrypt one thing with an AES/CBC/NoPadding cipher. In different phrases: we will write the Android Keystore suitable CMAC operate impartial of the important thing itself:

enjoyable cmac(message: ByteArray, cipher: () -> Cipher): ByteArray 

The AES/CBC cipher is offered within the Android Keystore, really we use it within the authentication course of. So we simply must implement the remainder of the CMAC algorithm ourselves. The unique CMAC paper seems to be very difficult, however fortunately there are a lot of implementations already. I check with the implementation of crypto swift to know how this works. Ultimately it boils right down to chopping the message into blocksized components, some bitshifting, encryption and xor’ing. In the event you applied the AuthenticateEV2First course of up up to now, it’s simple as pancakes.

Wrap up

Lastly, we’re in a position to do steps 1 to three proving to the cardboard that the telephone is authorised to determine encrypted communication. And we’re even in a position to calculate the session keys in step 4 and talk encrypted in CommunicationMode.Full. All in all it isn’t simple to implement the method utilizing an Android Keystore key. However in the long run it really works and the AES-key is as protected as potential!

Due to Stefan Schrass and my crew at Deutsche Bahn who made this work potential.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles