Аутентификация с Mifare Plus EV2 SL3JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Аутентификация с Mifare Plus EV2 SL3

Сообщение Anonymous »

Хороший день.
Несколько дней назад я приобрел терминал (модель P18Q), который поддерживает различные методы аутентификации для карт Mifare Plus. Поставщик сообщил мне, что мне нужно внедрить свои собственные алгоритмы шифрования для связи с картой, которая работает в режиме SL3, и для аутентификации в определенном секторе. Однако при использовании моей пользовательской реализации - где я отправляю свой ключ AES вместе с ответом на вызов - я последовательно сталкиваюсь с ошибкой во время процесса MPLUS_FIRSTAUTH_F2. < /P>
Кто -нибудь знает, правильно ли я выполняю аутентификацию? К сожалению, я не могу использовать официальную библиотеку NXP на этом терминале, так как в нем отсутствует стандартный читатель Android NFC. Вместо этого он связывается только через Apdus с внешним терминалом. Я делаю что -то не так? Это моя первая работа с этим типом карты. < /P>
public void test_MifarePlus() {
final int CID = 0;
final int fsdi = PICC_FSD_256;
int DRI = PICC_BITRATE_TXRX_106K;
int DSI = PICC_BITRATE_TXRX_106K;

clearLog();
appendLog("Iniciando autenticación Mifare Plus...");

try {
appendLog(">>> Paso 1: Detectando tarjeta...");
String uid = detectNfcCard();
if (uid == null || uid.isEmpty()) {
appendLog("Error: No se detectó tarjeta NFC");
return;
}
appendLog("Tarjeta detectada. UID: " + uid);

appendLog("\n>>> Paso 2: Activando tarjeta...");
String ATS = activateTypeACard(fsdi, CID);
if (ATS == null || ATS.length() < 2) {
appendLog("Error: Fallo en activación de tarjeta");
return;
}

byte[] atsBytes = ByteArrayTools.hexStringToByteArray(ATS);
int[] rates = PICC_ParseRate(atsBytes);
DRI = rates[0];
DSI = rates[1];

appendLog("ATS recibido: " + ATS);
appendLog("Parámetros negociados - DRI: " + DRI + ", DSI: " + DSI);

appendLog("\n>>> Paso 3: Solicitud PPS...");
int ppsStatus = requestPPS(CID, DRI, DSI);
if (ppsStatus != 0) {
appendLog("Error: Fallo en PPS (Código: " + ppsStatus + ")");
return;
}
appendLog("PPS exitoso");

appendLog("\n>>> Paso 4: Configurando autenticación SL3...");
P18QMifarePlus channel = new P18QMifarePlus();
MifarePlus mifarePlus = new MifarePlus(channel);

byte[] keyAES;
try {
keyAES = ByteArrayTools.hexStringToByteArray(AESKey);
if (keyAES == null || keyAES.length != 16) {
appendLog("Error: Clave AES inválida. Debe ser de 16 bytes");
return;
}
} catch (IllegalArgumentException e) {
appendLog("Error: Formato de clave AES inválido");
return;
}

appendLog("\n>>> Paso 5: Autenticación F1...");
int blockToAuth = 0x4002;
byte[] encryptedChallenge = mifarePlus.mplus_firstAuth_f1(blockToAuth);

if (encryptedChallenge == null || encryptedChallenge.length < 16) {
appendLog("Error: Challenge inválido o autenticación F1 fallida");
return;
}
appendLog("Challenge cifrado recibido: " +
ByteArrayTools.byteArrayToHexString(encryptedChallenge));

byte[] randB;
try {
randB = aesDecrypt(Arrays.copyOf(encryptedChallenge, 16), keyAES);
if (randB == null || randB.length != 16) {
appendLog("Error: Descifrado de RAND_B fallido");
return;
}
} catch (Exception e) {
appendLog("Error al descifrar RAND_B: " + e.getMessage());
return;
}

appendLog("RAND_B descifrado: " + ByteArrayTools.byteArrayToHexString(randB));

byte[] randB_rot = rotateLeftByte(randB);
byte[] randA = generateSecureRandom(16);
byte[] responseData = concatenateArrays(randA, randB_rot);

appendLog("RAND_A generado: " + ByteArrayTools.byteArrayToHexString(randA));
appendLog("RAND_B rotado: " + ByteArrayTools.byteArrayToHexString(randB_rot));

appendLog("\n>>> Paso 6: Autenticación F2...");
byte[] encryptedResponse;
try {
encryptedResponse = aesEncrypt(responseData, keyAES);
} catch (Exception e) {
appendLog("Error al cifrar respuesta F2: " + e.getMessage());
return;
}

appendLog("Datos a enviar (cifrados): " +
ByteArrayTools.byteArrayToHexString(encryptedResponse));

byte[] authResponse = mifarePlus.mplus_firstAuth_f2(encryptedResponse);
if (authResponse == null || authResponse.length == 0) {
appendLog("Error: Respuesta de autenticación F2 inválida");
return;
}

if (authResponse[0] != (byte) 0x90) {
appendLog("Autenticación fallida. Código de error: " +
String.format("%02X", authResponse[0]));
return;
}

appendLog("\nAutenticación SL3 completada con éxito!");
appendLog("Respuesta final: " + ByteArrayTools.byteArrayToHexString(authResponse));

} catch (Exception e) {
appendLog("Error crítico: " + e.toString());
e.printStackTrace();
} finally {
try {
int removalStatus = removeCPUCard();
appendLog(removalStatus == 0 ? "Operación completada" : "Error al remover tarjeta");
} catch (Exception e) {
appendLog("Error al limpiar: " + e.getMessage());
}
}
}

private byte[] aesEncrypt(byte[] data, byte[] key) throws Exception {
if (data == null || key == null) {
throw new IllegalArgumentException("Datos o clave nulos");
}

Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(data);
}

private byte[] aesDecrypt(byte[] data, byte[] key) throws Exception {
if (data == null || key == null) {
throw new IllegalArgumentException("Datos o clave nulos");
}

Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(data);
}

private byte[] rotateLeftByte(byte[] input) {
if (input == null || input.length == 0) {
throw new IllegalArgumentException("Array de entrada inválido");
}

byte[] output = new byte[input.length];
System.arraycopy(input, 1, output, 0, input.length - 1);
output[input.length - 1] = input[0];
return output;
}

private byte[] generateSecureRandom(int length) {
byte[] randomBytes = new byte[length];
new SecureRandom().nextBytes(randomBytes);
return randomBytes;
}

private byte[] concatenateArrays(byte[] a, byte[] b) {
byte[] result = new byte[a.length + b.length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length);
return result;
}
public byte[] mplus_firstAuth_f1(int key) throws Exception {
byte bloque1 = (byte) ( ( key >> 8 ) & 0xFF );
byte bloque2 = (byte) ( ( key ) & 0xFF );

byte[] apdu = new byte[4];

apdu[0] = 0x70;
apdu[1] = bloque2;
apdu[2] = bloque1;
apdu[3] = 0x00;

byte[] response = mplusMgr.sendApduCommand(apdu);

if ( response == null ) {
return null;
}

if ( response[0] == (byte) 0x90 ) {
return Arrays.copyOfRange(response, 1, response.length);
} else {
return null;
}
}
public byte[] mplus_firstAuth_f2(byte[] data) throws Exception {
if ( data == null ) {
return null;
}

byte[] apdu = new byte[data.length + 1];

apdu[0] = (byte) 0x72;
System.arraycopy(data, 0, apdu, 1, data.length);
byte[] response = mplusMgr.sendApduCommand(apdu);
return response;
}


Подробнее здесь: https://stackoverflow.com/questions/796 ... us-ev2-sl3
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Аутентификация с Mifare Plus EV2 SL3
    Anonymous » » в форуме JAVA
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Эффективное считывание данных с карт MiFare Plus (например, электронных паспортов) в Android
    Anonymous » » в форуме Android
    0 Ответы
    31 Просмотры
    Последнее сообщение Anonymous
  • Я получил ошибку времени выполнения C Plus Plus для начинающих при написании простой программы [закрыто]
    Anonymous » » в форуме C++
    0 Ответы
    97 Просмотры
    Последнее сообщение Anonymous
  • Как записать информацию на nfc-карту mifare Ultra Light EV1 с Android?
    Гость » » в форуме Android
    0 Ответы
    37 Просмотры
    Последнее сообщение Гость
  • Невозможно отправить коммандос Mifare на iOS (CoreNFC)
    Anonymous » » в форуме IOS
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»