当前位置: 首页 > 知识库问答 >
问题:

通过HID OMNIKEY 5427 CK向卡发送APDU命令

刘向阳
2023-03-14

我试图通过APDUs命令通过HID OMNIKEY 5427 CK操作MIFARE卡ie。超轻C卡,在Windows 10 x64操作系统环境下使用WinSCard.dll。(我隶属恩智浦NDA公司,可以完全访问他们的文件)

我试着在网上找了好几天的信息。除了2页的小册子,似乎没有针对这个模型发布的文档。

像GetUID(FFCA000000)这样的简单命令就可以了,我可以取回实际的卡UID。

但是对于“用卡验证”,HID 5421模型的参考文档说我应该从OpenGenericSession(FFA 0000703010001)开始,我尝试了,阅读器总是回复6D00h(错误)

我尝试直接发送身份验证命令“1Ah 00h”(FFA00005080100F30000641A0000),阅读器也总是回复错误代码。

我有过 HID 5421 型号的经验,它非常简单,不确定为什么这个 5427 与它的兄弟姐妹不同。

是的,我联系了HID支持。运气不好。我从他们那里得不到有用的信息。

如果任何人有想法或有5427软件开发指南,请帮助。到现在我已经拉了快一周的头发了。

共有1个答案

戚飞雨
2023-03-14

下面是使用 Omnikey 5321/6321 通过通用会话与 Ultralight-C 通信的概念验证 Java 代码:

private static final byte AF = (byte)0xAF;

protected static final byte[] PREFIX = new byte[] { 0x01, 0x00, (byte) 0xF3, 0x00, 0x00, 0x64 };

protected final CardChannel channel;

protected void openGenericSession() throws CardException {
    System.out.println("OPEN GENERIC SESSION");
    transmitAssert9000(new CommandAPDU(0xFF, 0xA0, 0x00, 0x07, new byte[] { 0x01, 0x00, 0x01}));
}

protected byte[] transmitRaw(byte[] data) throws CardException {
    System.out.println(" => " + toHex(data));
    byte[] ret = transmitAssert9000(new CommandAPDU(0xFF, 0xA0, 0x00, 0x05, ArrayUtils.addAll(PREFIX, data), 256));
    if(ret.length<2) {
        throw new RuntimeException();
    }
    if((ret[0]==0x00)&&(ret[1]==0x00)) {
        // Success
        ret = Arrays.copyOfRange(ret, 2, ret.length);
        System.out.println(" <= " + toHex(ret));
        return ret;
    }
    if((ret[0]==0x08)&&(ret[1]==0x04)&&(ret.length==3)) {
        // ACK/NAK
        switch(ret[2]) {
            case 0x0A:
                System.out.println(" <= ACK");
                return ArrayUtils.EMPTY_BYTE_ARRAY;
            default:
                // Buyer beware: very simplified
                System.out.println(" <= NAK");
                throw new RuntimeException("NAK");
        }
    }
    ret = Arrays.copyOfRange(ret, 2, ret.length);
    System.out.println(" <= " + toHex(ret));
    return ret;
}

protected static byte[] assert9000(ResponseAPDU transmit) {
    if(transmit.getSW()!=0x9000) {
        throw new RuntimeException("Unexpected response code");
    }
    return transmit.getData();
}

protected byte[] transmitAssert9000(CommandAPDU commandAPDU) throws CardException {
    return assert9000(transmit(commandAPDU));
}

protected ResponseAPDU transmit(CommandAPDU commandAPDU) throws CardException {
    System.out.println(" -> " + toHex(commandAPDU.getBytes()));
    ResponseAPDU responseAPDU = channel.transmit(commandAPDU);
    System.out.println(" <- " + toHex(responseAPDU.getBytes()));
    return responseAPDU;
}

public byte[] read(int offset) throws CardException {
    System.out.println("READ");
    return transmitRaw(new byte[] {0x30, (byte)offset});
}

注1:这段代码使用javax.smartcardio和Apache Commons Lang。

注2:我写这段代码已经有一段时间了,请验证我的想法...

注 3:有关 Ultralight-C 身份验证代码,请参阅此配套答案。

带有Ultralight-C的Omnikey 6321的通用会话示例跟踪(单线箭头表示通用会话APDUs,双线箭头表示Ultralight-C命令):

OPEN GENERIC SESSION
 -> FFA0000703010001
 <- 9000
AUTHENTICATE
 => 1A00
 -> FFA00005080100F30000641A0000
 <- 0000AF4BDA4E34B5D04A019000
 <= AF4BDA4E34B5D04A01
 => AF6F18402E0F0E5357D854833B149FBB56
 -> FFA00005170100F3000064AF6F18402E0F0E5357D854833B149FBB5600
 <- 000000F0F667CCF0E140419000
 <= 00F0F667CCF0E14041
READ
 => 3003
 -> FFA00005080100F3000064300300
 <- 0000000000000000000000000000000000009000
 <= 00000000000000000000000000000000
CLOSE GENERIC SESSION
 -> FFA0000703010002
 <- 9000

一些附加说明:

> (

  • AFAIK)这种方法在Windows下工作(使用Omnikey驱动程序)。它在 linux 下不起作用(即使使用 Omnikey 驱动程序)。

    请注意,PC/SC版本2.02第3部分定义了< code >管理会话、< code >透明交换和< code >交换协议命令,它们以标准化的方式提供相同的功能(您的读者可能会支持它,而不是专有的通用会话机制- HID甚至参与了本文档)。

    祝你好运

  •  类似资料:
    • 问题内容: 我已经使用过智能卡,并且熟悉APDU命令(在 ISO / IEC 7816 和 Global Platform 规范中定义)。 现在,我想知道是否有什么方法可以将APDU命令发送到插入手机的USIM / SIM卡?(安装了Android v4.4.4 kitkat的三星A3。) 我已经在Google中搜索过,发现了一些相关的主题和工具,名为 SIM Toolkit Applicatio

    • 我试图使用Dialogflow和twilio构建whatsapp聊天机器人。我注意到只有短信从twilio成功发送。 当我试图发送Dialogflow card时,twilio抛出一个错误。我从Dialogfunction内联编辑器中使用云函数发送卡片如下 虽然这在Dialogflow中工作得很好,但在WhatsApp上无法接收。只有短信在起作用。 是因为我目前在twilio沙箱还是他们不支持带有

    • 我正在尝试设置一个类,以便我可以通过ssh连接到远程服务器(我有IP、用户名和密码),然后发送类似“echo”test“”的命令,然后接收回输出(例如,“test”)。我用JSch来做这个,但我不知道怎么做。 我不知道该怎么办,连接后我卡住了。 非常感谢您的建议。

    • 我正在创建一个java应用程序,通过PC/SC非接触式阅读器和javax.smartcardioAPI与MifeDesFire卡通信。我设法发送常规的ISO 7816 APDU(CLA,INS,P1-P2,Lc,命令数据,Le)。 我在Ridrix的博客上读到,DESFire卡(至少我正在使用的EV1版本)支持APDU和本地命令,其中大多数命令只有1字节长。 例如,“获取版本”命令: 我用Spri

    • 我正在尝试将APDU命令发送到读卡器本身,而不是智能卡。我使用的测试命令打开和关闭射频场。 如果我第一次连接到智能卡,该命令将通过SCardTransmit发送。但一旦射频场关闭,卡就会断开连接,我无法发送另一个APDU来打开射频场。 基本上有什么方法可以在没有卡的情况下通过pc/sc发送APDU。我想在读卡之前配置读卡器的某些部分。 提前谢谢。 -----编辑----- 正如FPGA战士提到的,