Search code examples
securityencryptionnfcpaymentmifare

Payment application based on NTAG213 vs. Ultralight C (using Android NFC)


I have a (university) project where I basically write and read text out of an NFC tag with Android devices in order to store one's balance in the card (which can be used on the cafeteria, for example).

Right now, I'm using NTAG213 doing the below code:

ndef.connect();
NdefRecord mimeRecord = NdefRecord.createMime("text/plain", messageEncrypted.getBytes(Charset.forName("US-ASCII")));
ndef.writeNdefMessage(new NdefMessage(mimeRecord));
ndef.close();

As you can notice, I'm using application level encryption to encrypt the message (messageEncrypted) before writing it to the tag (AES-256 encrypt with 'com.scottyab:aescrypt:0.0.1' library - with a very big password key that uses also the tag UID as part of it).

So far so good - only I can understand the data on the tag.

On my research, I've found that when it comes to security Ultralight C > NTAG213.


Question 1) When using application level encryption, why (is it?) is MIFARE Ultralight C safer then NTAG213?

Question 2) I'm pretty sure I can guarantee security using AES encryption, but I don't want people (besides me) messing with the stored data (formatting tag or writing info there). I see that the only way of preventing that (please, correct me if I'm wrong) is to set a password for the tag. However, both NTAG213 and Ultralight C have only an 32-bit password. Is it good enough? Is there another way of preventing someone (besides me) writing data?

Question 3) Which other security measures can I use on such tags to enforce security (tag and application layer)?

Question 4) When you compare tag security (MIFARE DESFire > Ultralight > NTAG213 > MIFARE Classic), what is really being compared? The ease of one cracking the (native tag's) encryption or the ease of one store (anything) on the tag without permission?

Question 5) I see a bunch of other techs (MIFARE DESFire, ICODE SLIX, Infineon Cipurse) that are more secure, which makes me wonder if the tech I'm using (NTAG213 or Ultralight C) is good enough for storing someones balance. Would you (and that's a personal opinion) say that NTAG213 with application level encryption and 32-bit password good enough for this type of application? And how long would it take someone to actually break its security?


Solution

  • When using application level encryption, why is Ultralight C safer then NTAG213? Is that even true?

    First of all, "safer" depends on what your actual protection goals are. Since you want to store a balance (cash money!) on the card, you would probably want to (at least) protect towards the following goals:

    • Users must not be able to print their own money by setting an arbitrary balance on their card.
    • Users must not be able to duplicate their card and, consequently, their money balance.
    • Users must not be able to print their own money by restoring (roll-back) their card to a previous balance after payment.
    • Users must not be able to print their own money by replaying a top-up procedure.
    • Users must not be able to evade payment by tearing their card during a payment transaction.
    • Users must not be able to generate an arbitrary (and potentially higher) balance on their card by tearing their card during a top-up procedure.

    In addition, you might not want to trust operators (the persons accepting payments and performing top-up) as well. In a system where one group of operators performs only top-up and the other performs only payment transactions, the latter group should probably not be allowed to ever "create" money. Particularly, you have to make yourself very clear about whether you fully trust the (Android) devices that you use in the field to perform these operations and whether you trust operators (e.g. that they don't perform any attacks against these devices).

    Moreover, there might be privacy aspects that you need to consider (e.g. if the balance is freely readable, if users are identifiable, etc.)

    So let's look into what you "application level encryption" adds in terms of security:

    • Since users do not know the encryption key, they are probably not able to generate an arbitrary balance on their card. However, this heavily depends on the format of your balance (in unencrypted form). Users can make arbitrary modifications to the cipher text with result in "random" modifications of the plain text. Consequently, users may be able to modify the balance value despite encryption. Digital signature/message authentication codes are they path that you would probably want to take to overcome this.
    • Since the encryption key (assuming encryption would be sufficient, which it probably is not) depends on the UID of the tag, you may be safe against cloning of cards (+ balance). However, be aware that the UID is just a freely readable identifier. It is by no means authenticated itself and may be clonable as well. See Serials on NFC Tags - truly unique? cloneable?.
    • The encrypted value does not protect you from users restoring their balance to a previously recorded value after payment. This type of vulnerability has been found before (particularly in MIFARE Ultralight based systems), see, for instance, Benninger, C., Sobell, M. (2012): NFC for free rides and rooms (on your phone). In: Presentation at EUSecWest 2012.
    • Since you write the complete value during a top-up procedure (i.e. there is no specific "increment balance" command), you are probably safe against users replaying a top-up (except for the roll-back aspect of this).
    • Effects of tearing are probably rather limited if your system only allows for attended payment/top-up.

    So let's see what additional features NTAG213 would have that you could use to secure your system:

    • UID is unique on genuine tags. This does not help much, see Serials on NFC Tags - truly unique? cloneable?.
    • Originality signature: same as above, the originality signature is also just a static, freely readable value. Consequently, it's just as well susceptible to cloning.
    • The one-way counter might be a tool to help you in protecting against roll-back (by including the counter value into the signature). This still would not prevent cloning onto a tag platform that allows to generate arbitrary counter values. Moreover, the counter is not easily controllable and will change its value if the user tries to read the tag. Consequently, it's questionable if an implementation based on that value would be reliable.
    • Unlike MIFARE Ultralight, NTAG213 does not have a usable one-time programmable area (since that's already used by the capability container). Consequently, you can't implement a one-time deductible balance based on that.
    • The password protection feature could help you in authenticating tags (by performing password verification) and in protecting the value stored on the tag (by making the value only readable/writable after password verification). However, the password is transmitted in clear text (may be subject to sniffing, particularly in (but not limited to) unattended scenarios) and there is no cryptographic binding between the password and the actual read/write.

    MIFARE Ultralight C would add the following:

    • The OTP bytes can be used. If it's an option to make the tags one-time usable (i.e. they start with a specific balance that can only be deducted from and not topped-up), then using the OTP bytes to represent the balance would be an option. Note that there's still lots of things that you could do wrong with that, e.g. Beccaro, M., Collura, M. (2013): OTP circumventing in MIFARE ULTRALIGHT: Who says free rides?. In: Presentation at DEFCON 21
    • The authentication is much improved. The 3DES authentication scheme seems to be sufficiently secure to prevent sniffing the key. However, read/write commands are also not cryptographically bound to the authentication step. Consequently, an attacker might be able to let a genuine payment terminal + genuine tag perform authentication, but redirect read/write to somewhere else. This might (particularly) be a problem in an unattended scenario.

    I'm pretty sure I can guarantee security using AES encryption.

    See above. This is probably not true.

    I don't want people messing with the stored data. I see that the only way of preventing that is to set a password for the tag.

    A password/authentication key may help, but be aware of the limitations due to authentication being decoupled from read/write on these tag platforms.

    Both NTAG213 and Ultralight C have only a 32-bit password.

    This is not true. NTAG213 has a 32-bit password. MIFARE Ultralight C uses a more sophisticated mutual 2K-3DES authentication mechanism with a 112-bit key.

    When you compare tag security, what is really being compared?

    • Authentication mechanisms (algorithms, key sizes)
    • Communication security (e.g. is the communication itself encrypted/authenticated using a session key derived from the authentication step?)
    • Access control (e.g. are there separate keys for top-up and payment?)
    • Are there dedicated mechanisms for balance management (e.g. value fields, dedicated increment/decrement operations)? And, consequently, are ther mechanisms to protect agains tearing attacks?
    • And probably more ...

    I see a bunch of other techs that are more secure, which makes me wonder if the tech I'm using is good enough for storing someones balance.

    You specific system is flawed in many ways. In my opinion MIFARE Ultralight/NTAG203/NTAG21x are definitely not a good choice for a an offline system storing cash money on the cards.

    MIFARE Ultralight C may be suitable with some precautions. I would definitely refrain from using that in unattended scenarios, and I would probably use an online system tracking the balance and monitoring for inconsistencies.

    Anything that uses symmetric cryptography and storing the cryptographic keys in a terminal would certainly require precautions against malicious operators. It's probably fairly easy for an operator (with some knowledge) to extract keys from an app and generate their own money.