AndroidCrypto / Ntag424SdmFeature

This is an accompanying application to an articles series about demystifying the Secure Dynamic Message feature of NTAG 424 DNA NFC tags.
MIT License
6 stars 6 forks source link

Problem in EncryptedSunActivity #1

Open AndroidCrypto opened 1 month ago

AndroidCrypto commented 1 month ago

This issue was reported by user Unaibox in Sep. 2024:

Awesome post!!!, it's helping me a lot to move forward with technology. I have a doubt, I am using EncryptedSunActivity to use uid x count + cmac and my goal is to encrypt it with a key (23450000000000000000000000000000000000000ABC).

For this in Constants (Android Studio) I indicated APPLICATION_KEY_2 = Utils.hexStringToByteArray(‘234500000000000000000000000000000000000000000ABC’);

And in the verification backend (config.py) "MASTER_KEY = binascii.unhexlify(‘234500000000000000000000000000000000000000000ABC’)", but it doesn't work.

However, if in the backend I put "MASTER_KEY = binascii.unhexlify(‘00000000000000000000000000000000’)" it allows me to access without problems, that is, the Android APP is not applying the key and I have followed the tutorial:

sdmSettings.sdmMetaReadPerm = ACCESS_KEY2;
sdmSettings.sdmFileReadPerm = ACCESS_KEY2

Hope you can help me to figure out what's happening Thanks and Regards!

Additional comment by "Unaibox":

Reviewing the post, I see that I have to use the option for custom keys, but the NFC developer backend is unable to decrypt it even when specifying MASTER_KEY = binascii.unhexlify("A4000000000000000000000000000000"), which is supposedly the key with which everything has been encrypted

AndroidCrypto commented 1 month ago

In the following you find excerpts from the code of the EncryptedSunCustomKeysActivity (here I'm using the Custom Keys instead of DEFAULT_KEYS):

Header:

import static net.bplearning.ntag424.constants.Permissions.ACCESS_KEY0;
import static net.bplearning.ntag424.constants.Permissions.ACCESS_KEY2;
import static net.bplearning.ntag424.constants.Permissions.ACCESS_KEY3;
import static net.bplearning.ntag424.constants.Permissions.ACCESS_KEY4;
import static net.bplearning.ntag424.constants.Permissions.ACCESS_NONE;

In private void runWorker() {:

// write URL template to file 02 depending on radio button                                                               
SDMSettings sdmSettings = new SDMSettings();                                                                             
sdmSettings.sdmEnabled = true; // at this point we are just preparing the templated but do not enable the SUN/SDM feature
sdmSettings.sdmMetaReadPerm = ACCESS_KEY3; // Set to a key to get encrypted PICC data                                    
sdmSettings.sdmFileReadPerm = ACCESS_KEY4; // Used to create the MAC and Encrypted File data                             
sdmSettings.sdmReadCounterRetrievalPerm = ACCESS_NONE; // Not sure what this is for           

The sdmMetaReadPerm key is set to Key_3 and the sdmFileReadPerm key is set to KEY_4. In the Constants.java they are defined as:

public static final byte[] APPLICATION_KEY_3 = Utils.hexStringToByteArray("A3000000000000000000000000000000");
public static final byte[] APPLICATION_KEY_4 = Utils.hexStringToByteArray("A4000000000000000000000000000000");

The keys itself are set in the PrepareActivity.java for the Main Application of the NTAG424 tag (the tag itself needs to know the key it should use for operation) in the private void runWorker() { method (the code is just the change key 3 code:

...
// change application key 3                                                                                    
success = false;                                                                                               
try {                                                                                                          
    ChangeKey.run(dnaC, ACCESS_KEY3, APPLICATION_KEY_DEFAULT , APPLICATION_KEY_3, APPLICATION_KEY_VERSION_NEW);
    success = true;                                                                                            
} catch (IOException e) {                                                                                      
    Log.e(TAG, "ChangeKey 3 IOException: " + e.getMessage());                                                  
}                                                                                                              
if (success) {                                                                                                 
    writeToUiAppend(output, "Change Application Key 3 SUCCESS");                                               
} else {                                                                                                       
    writeToUiAppend(output, "Change Application Key 3 FAILURE, Operation aborted");                            
    return;                                                                                                    
} 
...       

where ChangeKey.run is defined as:

public static void run(     @NonNull     DnaCommunicator communicator,
    int keyNum,
    byte[] oldKey,
    byte[] newKey,
    int keyVersion )

so I'm going the ACCESS_KEY3 from oldKey ("APPLICATION_KEY_DEFAULT") to newKey ("APPLICATION_KEY_3").

Please do not mix the keys for the (external used) SDM feature (KEY_3 and KEY_4) with the keys used internally to write the data like the URL_TEMPLATE to the tag or change the file settings for enabling the SDM feature (KEY_0, KEY_1 and KEY_2). Especially when I authenticate the NTAG424 I'm using the factory key:

success = AESEncryptionMode.authenticateEV2(dnaC, ACCESS_KEY0, Ntag424.FACTORY_KEY);

I left KEY_0 ("Master Application Key") unchanged because when changing this key (e.g. during testing with different data) to a unknown value ("unknown" = some times later when you forgot this key...) the key may get unusable as there is no way to recover this key.

A note on https://github.com/nfc-developer/sdm-backend: I never worked with the source code of this repository, I'm just using the backend server for an easy verification of the created NDEF messages. I do not know what keys need to set to decrypt and verify the data created with "Custom" keys.

I hope that helped. Michael