使用PC / SC读卡器验证Ultralight EV1 [英] Authenticating Ultralight EV1 with PC/SC reader

查看:238
本文介绍了使用PC / SC读卡器验证Ultralight EV1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用Java中的PC / SC阅读器(特别是ACR1222L)验证Ultralight EV1卡时遇到问题。我可以使用相应的ISO 14443-3标签APDU来编写和读取未受保护的标签。但是,我找不到运行PWD_AUTH命令的方法,因为它不是14443-3标准(或任何本机命令)的一部分。是否可以运行此命令(或任何本机命令)?

I have a problem trying to authenticate an Ultralight EV1 card using a PC/SC reader (specifically an ACR1222L) in Java. I'm able to write and read on an unprotected tag using the corresponding APDUs for ISO 14443-3 tags. However, I can't find a way to run the PWD_AUTH command since it is not part of the 14443-3 standard (or any native command for that matter). Is it possible to run this command (or any native command for that matter)?

我尝试发送以下APDU {e0 00 00 24 07 1b ff ff ff ff 63 00}其中1b是本机命令,ff ff ff ff是密码和63 00是命令的CRC_A加密码。我也试过没有CRC,切换参数的顺序等,但到目前为止我无法使它工作。

I have tried sending the following APDU {e0 00 00 24 07 1b ff ff ff ff 63 00} where 1b is the native command, ff ff ff ff is the password and 63 00 is the CRC_A of the command plus password. I have also tried without the CRC, switching the order of the parameters, etc., but so far I could not get it working.

我也尝试包装APDU(如 https://stackoverflow.com/a/41729534/3613883 中所述。我得到了它与Desfire EV1卡一起工作,但它不适用于超轻EV1(因为它显然不支持ISO7816-4)。

I also tried wrapping the APDU (as described in https://stackoverflow.com/a/41729534/3613883). I got it working with a Desfire EV1 card but it doesn’t work with the ultralight EV1 (since it doesn’t support ISO7816-4 obviously).

所以,是有没有办法使用PC / SC读卡器验证Ultralight EV1卡?

So, is there a way to authenticate a Ultralight EV1 card using a PC/SC reader?

推荐答案

首先,MIFARE Ultralight EV1没有说APDU。相反,它使用直接基于ISO / IEC 14443-3中定义的成帧的命令。由于ISO / IEC 14443-3仅定义了成帧和防冲突/枚举命令,因此除此之外的任何协议(例如MIFARE Ultralight / NTAG命令集)都是专有的。

First of all, MIFARE Ultralight EV1 does not speak APDUs. Instead it uses commands based directly on the framing defined in ISO/IEC 14443-3. Since ISO/IEC 14443-3 only defines the framing and the anti-collision/enumeration commands, any protocol on top of that (e.g. the MIFARE Ultralight/NTAG command sets) is proprietary.

使用密码 FF FF FF FF 进行密码验证的正确命令为:

The correct command for password authentication using the password FF FF FF FF would be:

byte[] tagCommand = new byte[] { (byte)0x1B, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF };

请注意,CRC通常由非接触式前端芯片处理,因此您不需要apped手动。

Note that the CRC will typically be handled by the contactless frontend chip so you don't need to apped it manually.

使用ACR1222L,有多种不同的方式来交换这些专有命令:

With the ACR1222L, there are multiple different ways to exchange such proprietary commands:


  1. 您可以使用PC_to_RDR_Escape(请注意,只有在为阅读器安装了原始ACR驱动程序包时才可用)。假设您使用的是Java Smartcard IO API,您可以使用方法 Card.transmitControlCommand()

byte[] response = card.transmitControlCommand(SCARD_CTL_CODE(3500), command);

方法 SCARD_CTL_CODE 的定义可以是在这篇文章中找到

The definition of the method SCARD_CTL_CODE can be found in this post.

command 需要是一个字节数组,其中包含伪APDU的APDU头,它将原始命令传递给非接触式前端芯片,以及非接触式前端芯片的实际命令。由于ACR1222L基于NXP PN532(?),因此非接触式前端芯片的命令将是InDataExchange命令(请参阅用户手册):

The command needs to be a byte array that contains an APDU header for the pseudo-APDU that passes raw commands to the contactless frontend chip and the actual command for the contactless frontend chip. Since the ACR1222L is based on an NXP PN532(?), the command for the contactless frontend chip would be the InDataExchange command (see the user manual):

byte[] interfaceCommandHeader = new byte[] { (byte)0xD4, (byte)0x40, (byte)0x01 };
byte[] interfaceCommand = Arrays.copyOf(interfaceCommandHeader, interfaceCommandHeader.length + tagCommand.length);
System.arraycopy(tagCommand, 0, interfaceCommand, interfaceCommandHeader.length, tagCommand.length);

根据读者实际激活卡的方式,您可能需要使用InCommunicateThru命令而不是InDataExchange :

Depending on how the reader actually activates the card, you might need to use the InCommunicateThru command instead of InDataExchange:

byte[] interfaceCommandHeader = new byte[] { (byte)0xD4, (byte)0x42 };
byte[] interfaceCommand = Arrays.copyOf(interfaceCommandHeader, interfaceCommandHeader.length + tagCommand.length);
System.arraycopy(tagCommand, 0, interfaceCommand, interfaceCommandHeader.length, tagCommand.length);

伪APDU标头可以添加:

The pseudo APDU header can be added by:

byte[] commandHeader = new byte[] { (byte)0xE0, (byte)0x00, (byte)0x00, (byte)0x24, (byte)0x00 };
byte[] command = Arrays.copyOf(commandHeader, commandHeader.length + interfaceCommand.length);
System.arraycopy(interfaceCommand, 0, command, commandHeader.length, interfaceCommand.length);
command[4] = (byte)(interfaceCommand.length & 0x0FF);  // update Lc field


  • 另一种选择是使用PC_to_RDR_XfrBlock直接发送命令。这映射到Java Smartcard IO API中的 CardChannel.transmit()

    ResponseAPDU responseApdu = cardChannel.transmit(commandAPDU);
    

    读者手册不太清楚是否可以在该接口上使用相同的伪APDU报头。但是,如果你看一下附录H,你会发现一个不同的标题包装成伪APDU(ACR122U传统模式)。所以你可以使用以下内容:

    The manual of your reader is not quite clear if the same pseudo APDU header can be used over that interface. However, if you look into appendix H, you'll find a different header from wrapping into a pseudo APDU (the ACR122U legacy mode). So you could use the following:

    CommandAPDU commandAPDU = new CommandAPDU(0xFF, 0x00, 0x00, 0x00, interfaceCommand);
    

    请注意,同样,您必须将tag命令包装到非接触式前端芯片的InDataExchange命令中。

    Note that, again, you have to wrap the tag command into the InDataExchange command for the contactless frontend chip.

    这篇关于使用PC / SC读卡器验证Ultralight EV1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆