Forum / MIFARE SDK / Cannot ChangeKey, Get 1E response.
Tagged: 1
-
Hi,
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.
Regards,
Warren
+ 0 | - 1
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
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.
Regards,
Warren
+ 0 | - 0
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);
break;
case 16:
case 24:
encryptionKey = sessionKey;
break;
default:
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
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
-
AuthorPosts
Viewing 5 posts - 1 through 5 (of 5 total)
You must be logged in to reply to this topic.