piotrekwitkowski / LibraryNFC

MIFARE DESFire NFC Reader and HCE Emulator apps for Android
48 stars 14 forks source link

How to read enciphered data? #2

Closed JKorsten closed 3 years ago

JKorsten commented 3 years ago

Is it also possible to read enciphered data using your project?

piotrekwitkowski commented 3 years ago

What exactly do you mean by enciphered?

The default DESFire Read Data command is BD. Once you have selected the Application (and, if needed, authenticated yourself), you can use it like this: BD + File No. (1 byte) + Data Offset (3 bytes) + Data Length (3 bytes). Any furter encryption and decryption of the data may be implemented and realized in the card reader. The LibraryReader Android application does not provide any of this, it gives you just raw DESFire Read Data output.

JKorsten commented 3 years ago

That's indeed what I do, I ready your documentation: https://github.com/revk/DESFireAES/blob/master/DESFire.pdf And with ready data you write: The response will have MAC or be enciphered depending on file comm mode. Is there a way to set the comm mode because I know I have an enciphered mode of communication.

piotrekwitkowski commented 3 years ago

Ah, I get you now. You set the communication mode during file creation and it is possible to change it afterwards with the 5F: Change FileSettings command, see page 12 of the aforementioned doc (it's not mine, btw 😅). But you have to encrypt the 5F command body in order to change it, and unfortunately it is not implemented in the Reader app, I do not save the session key after AES auth, because I didn't need it then...

So you probably need to store the authentication result and implement CRC generation in the app, then use it to decipher your data or set the comm mode to MAC-based. Should be doable, a PR would be more then welcome :) and feel free to reopen, in case of any questions!

JKorsten commented 3 years ago

I don't want to change the file settings. So the command 5F won't be used. What authentication result should I store and how do I use it to decipher the response from the read command? (Sorry I don't really understand the Cipher class and all the IV stuff)

piotrekwitkowski commented 3 years ago

During the (symmetric) auth phase the card and reader both generate random values and send them to the second device. Then, they both encrypt the bytes they got and send back. With a symmetric key, they can decide if the key the second device has is the same key they have without actually exchanging it.

Once the auth is complete and successful, these randoms create a Session Key for further communication. You have to extend the app and save these random values and pass the session key to the next "states" of the app's state machine. random A: AA AA AA AA bb bb bb bb cc cc cc cc DD DD DD DD random B: EE EE EE EE ff ff ff ff gg gg gg gg HH HH HH HH

Knowing these randoms, the session key (for AES auth) looks like this, I hope I remember correctly: session key: AA AA AA AA EE EE EE EE DD DD DD DD HH HH HH HH

But I don't remember now for sure how to use the session keys for IV (initialization vector), sorry! Maybe this or stack will help you further.

JKorsten commented 3 years ago

Thanks, I'll have a look at it.