Cannot ChangeKey, Get 1E response.

Forum / MIFARE SDK / Cannot ChangeKey, Get 1E response.


  • 15. March 2016 at 16:20

    I am struggling to change the application master key on a DesFire card. I am authenticating OK with the default master key, but ChangeKey always returns the error. Can someone confirm the steps necessary to change key and in particular what CRC16 algorithm to use? Also, is it possible to change from the default single DES key to a double length key?

    Steps I am doing:

    Select Application.
    Authenticate to get the Session Key.
    Calculate CRC16-CCITT (0xFFFF) for the double DES key.
    Append CRC16 and 6 padding bytes.
    Single DES decryption CBC mode with IV set to zeros and with session key (1st half only because single DES)

    I suspect that the problem is down to the CRC16 but don't know what other algorithm to use.


    + 0  |  - 1

    Re: Cannot ChangeKey, Get 1E response.

    16. March 2016 at 9:59
    Hi Warren,

    Change the key does not implicit calculation necessarily, except you want to use a key diversification method. I would never “calculate” a master key, I would always use it from a (true) random source. This key value is saved onto the card with the ChangeKey() method.

    A “session key” is used internally while the session after a successful authentication is running. This is not the card key!

    Kind regards,
    The MIFARE Team
    + 0  |  - 0

    Re: Cannot ChangeKey, Get 1E response.

    16. March 2016 at 10:28
    I'm not sure I follow. There is a Card Master Key (CMK) and a Application Master Key (AMK) which have default valuers of all zeros. I want to change these using ChangeKey command. According to the documentation I have this is done by decrypting with the session key:

    In case the KeyNo used for authentication is the SAME as the KeyNo to be changed or if ChangeKey
    Key is set to 0xE, the PCD needs to generate the data frame “deciphered key data” in the following way:
    A CRC (2 bytes) is calculated over the new key data (16 bytes) and appended at the end. After this padding
    of zeros (6 bytes) is applied to reach an adequate frame size of multiples of 8 (24 byte overall). Finally a
    DES/3DES deciphering operation (using the current session key) is performed on the whole key data field.
    The three cryptogram blocks are chained using the CBC send mode.

    The problem is I can't get it to work, I get the error response 1E.


    + 0  |  - 0

    Re: Cannot ChangeKey, Get 1E response.

    16. March 2016 at 11:20
    This is a code example:

    public void ChangeKey(byte keyNo, byte[] sessionKey, byte[] key)
    if (key == null)
    throw new ArgumentNullException("key");

    if (key.Length != 16)
    throw new ArgumentException("Invalid key length.");

    byte[] encryptionKey;

    switch (sessionKey.Length)
    case 8:
    encryptionKey = new byte[16];
    Array.Copy(sessionKey, 0, encryptionKey, 0, 8);
    Array.Copy(sessionKey, 0, encryptionKey, 8, 8);
    case 16:
    case 24:
    encryptionKey = sessionKey;
    throw new ArgumentException("Invalid session key length. Must be single, double or triple DES.");

    byte[] versionedKey = Common.Utils.VersionKey(0, key);

    //ushort crc1 = Common.CheckSum.CalculateCRC16(versionedKey);
    byte[] crc = Common.CheckSum.DESFireCRC(versionedKey);

    byte[] data = new byte[24];
    Array.Copy(versionedKey, 0, data, 0, 16);
    data[16] = crc[0]; // (byte)crc;
    data[17] = crc[1]; // (byte)(crc >> 8);
    data[18] = 0x00;
    data[19] = 0x00;
    data[21] = 0x00;
    data[22] = 0x00;
    data[23] = 0x00;

    byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
    byte[] cmd = new byte[26];
    cmd[0] = 0xC4;
    cmd[1] = keyNo;

    using (TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider())
    provider.Mode = CipherMode.CBC;
    provider.BlockSize = 64;
    provider.KeySize = encryptionKey.Length * 8;
    provider.Padding = PaddingMode.None;

    using (ICryptoTransform transform = Common.TripleDESCryptoServiceProviderHelper.CreateWeakDecryptor(provider, encryptionKey, iv))
    byte[] encryptedData = transform.TransformFinalBlock(data, 0, data.Length);
    Array.Copy(encryptedData, 0, cmd, 2, 24);

    byte[] response = _reader.Transmit(cmd);

    if ((response.Length != 1) || (response[0] != 0))
    throw new Common.CardException("A6118", String.Format("Failed to change key number 0x{0:X2}. Status 0x{1:X2}.", keyNo, response[0]));

    + 0  |  - 0

    Re: Cannot ChangeKey, Get 1E response.

    16. March 2016 at 15:12
    Hi Warren,

    Do you sure you are in the right site? We are talking about the MIFARE SDK for Android which is written in Java. When I see your code snippet it looks a little bit strange for me. For example the class TripleDESCryptoServiceProvider is part of the .NET framework for C#. You are trying to develop an app for the PC or Windows Phone, right?

    Sorry, but the MIFARE Team cannot give analytics for foreign frameworks.

    The MIFARE Team
    + 0  |  - 0
Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.