NFC Mifare Ultralight encryption

Hi folks,

I’ve managed to create an read/write NFC integration using Ionic native NFC. Works well.

However, I’m interested in securing the data on our Mifare Ultralight EV1 tags… Has anyone got any suggestions on how to get this working?

I tried encrypting with RSA manually first, but the payload becomes a bit too big (1K/4K RFID chips are too costly for our purposes and won’t be practical in this case).

Best,
Rikki

Using naked RSA to encode actual data (as opposed to key wrapping) is not a great idea for several reasons.

If you are willing to require users to enter a passphrase each time the app is started up, I would suggest looking into scrypt for key generation. There are probably several implementations of it that can be used in Ionic apps; I’ve used this one.

To do the actual encryption itself, I would recommend using WebCrypto. My personal recommended algorithm is AES-GCM, and there are examples of using it for encryption/decryption here. One problem is that iOS’s stock webview does not support this algorithm, but that can be worked around by installing the webkitview-engine plugin.

Hi @rapropos, thanks for the reply.

Our app is private and intended to be used across multiple Android devices. Would this mean the app would have to have an internally stored passphrase to enable the encryption/decryption to work on any device for the chips?

Bearing in mind the NFC UIDs are meant to be unchangeable, could it be used as a salt? I’ve read in one of the official data sheets that it can be used (and is recommended).

Have you done anything similar? Would be good to get some design input on this problem.

Cheers!

You will have to consider a tradeoff here. The point of a KDF like scrypt is that it generates keys from user-generated passphrases. If you’re going to burn the passphrase into the app, it doesn’t make sense to use a KDF at all; you might as well just burn the AES key in instead. This would make your app simpler to write (all you need to do is the AES-GCM encryption/decryption) and use (no need to enter passphrases).

However, the big problem with this approach is that anybody with access to the app binary (or a device with it installed) has everything necessary to decode all the information on the chips. The only way to avoid that is to have users input something that is never stored on the device, such as a passphrase at app startup time. If that is determined to be unacceptable for business reasons, you just need to make sure that the person making that decision understands the security impact and the fact that control over the app binary (and source) will likely become the weakest link in the security of the entire system.

If all your devices have access to a private server that could be used to distribute keys, that would be another option, but I haven’t implemented that part, so can’t say much more in terms of implementation details there.

I can’t think of how that would help. A blackhat with a copy of the app would still be able to read any chip, presuming that a whitehat with a copy of the app needs to be able to do so.

Not precisely when it comes to writing things to RFID chips, but as far as encrypted storage and transmission, yes, several times, but each system has its own set of specific requirements that determine the best shape for the system. From what I’ve heard from you so far, it seems that if you can live with the fact that the app binary needs to be secured as carefully as any key would be, then a hardcoded or server-distributed AES key used in GCM mode would be your best choice.

Thanks once again for your input @rapropos, some food for thought here for sure.

We do actually require the input of a password on startup from an admin user before handing over the device to a normal user… perhaps this should be cryptographically more secure and be used in the NFC part of the system?

Hmm. Offhand, I can’t think of any way to achieve this. Once the password from the admin user has been entered, presumably whitehat must be able to proceed decrypting anything without further input. If that is the case, I can’t see how to prevent blackhat from doing the same once they have the activated device.

Hi @rapropos, couldn’t the correct PIN/password login (by way of checking against the scrypt hash) be used again with a salt to generate a new hash that’s not held on the device for the purposes of NFC encryption?
Rikki

scrypt isn’t (typically, at least) used for checking correctness of things. At the end of the day, we need 128/192/256 bits of deterministic randomness to use as an AES key. Deterministic in the sense that whitehat can consistently regenerate it, and random in the sense that blackhat cannot easily do so. I obviously may be completely missing something, but I don’t see how any sort of per-chip salt helps anything, because both whitehat and blackhat have the exact same access to that NFC UID.

My thoughts were so that if a chip’s data is copied to another chip, it wouldn’t work as the app would compare the UID from the encrypted string and the UID of the read chip. If that makes sense?

The UID can be spoofed. But I think the answers to most of your questions depend on threat level context. Does your attacker have limited or unlimited resources? Also, the main private-entity attacks may well be social engineering, not hacking/cracking. So “I forgot my password” is probably more important than “here’s a secure Admin password.”

If you have an app and not just a paper ticket with a magstripe, why not require an internet connection to a secure server? Take all the security out of the app itself. An attacker with resources can see the entire app.

I’m not seeing the threat scenario that this would do anything against.

If blackhat has a copy of the app and access to the encrypted chip, they could simply decode the data at that point.

If we’re assuming two blackhats, one (A) who only has access to the chip and the other (B) has the app, then at the time (A) is cloning your secret chip to a spare in order to hand to (B) later, (A) can also note the UID of the original chip at the same time, so (B) can use that to generate the needed key.

Clearly I could be missing something, so if you can explain what threat scenario you’re envisioning, great. If I were in your shoes, though, I would consider it a feature that an unprivileged person (without access to the app) could clone an encrypted chip and have the clone work. Say you have some sort of outside contractor in charge of routinely replacing old chips as they reach X years of age or Y writes. You don’t want them able to access the data, but you do want them to be able to seamlessly persist data to new hardware.

So here are my concerns and a bit about the app we’re creating.

The devices and therefore app are private and used in our situation to scan RFID chips and write to them as required.

The operators won’t know the admin login password which is used for altering settings for the use case.

Devices could technically be stolen, they are handheld (not phones).

Devices may or may not have an internet connection (so cloud based encryption isn’t viable).

So here’s my thinking. The password isn’t stored on the device, but it’s used with some kind of hashing comparison to authenticate (like websites do). Then once the password is validated, use it along with a salt to generate a new hash that is used to do the AES encryption for the chips.

Does this sound viable?

Thanks for you input folks, really appreciated.

Rikki

Not to me, no.

In order for the password itself to be fed to a KDF, it would have to be something the operators know. If you’re talking about a case where the app is initially “disarmed”, and an admin “arms” them by entering the password, then a stolen “armed” device is game over.

Fundamentally, any operation capable of being carried out by a whitehat operator can be done by a blackhat with the same device, so if that presents an insurmountable problem, the only way I can think of to resolve it is to have operators enter something that blackhats do not know. Further complicating the issue is that if it’s necessary for operator B to be able to read what operator A has written to a chip, said secret must be shared.