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

2024-03-23

我正在尝试通过 HID OMNIKEY 5427 CK 通过 APDU 命令来操作 MIFARE 卡,即。 Ultralight C 卡,在 Windows 10 x64 操作系统环境上使用 WinSCard.dll。 (我已签署 NXP NDA,并且可以完全访问他们的文档)

我已经尝试在网上查找信息好几天了。除了两页的小册子之外,似乎没有关于该模型的公开文档。

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

但对于“卡身份验证”,HID 5421 模型的参考文档说我应该从 OpenGenericSession (FFA0000703010001) 开始,我尝试过,读者总是回复 6D00h(错误)

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

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

是的,我联系了 HID 支持人员。没有运气。我无法从他们那里得到任何有用的信息。

如果有人有想法或有 5427 软件开发指南,请帮忙。我现在已经拉头发快一个星期了。


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

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 https://docs.oracle.com/javase/8/docs/jre/api/security/smartcardio/spec/javax/smartcardio/package-summary.html and 阿帕奇公共语言 https://commons.apache.org/proper/commons-lang/.

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

注 3:有关 Ultralight-C 验证码,请参阅此同伴回答 https://stackoverflow.com/a/44640515/5128464.


使用 Ultralight-C 的 Omnikey 6321 的通用会话示例跟踪(单线箭头表示通用会话APDU 和双线箭头表示 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 部分 http://pcscworkgroup.com/Download/Specifications/pcsc3_v2.02.00_sup2.pdf定义MANAGE SESSION, TRANSAPARENT EXCHANGE and SWITCH PROTOCOL以标准化方式提供相同功能的命令(您的读者可能支持它而不是专有的通用会话机制——HID 甚至参与了本文档)。

祝你好运!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 HID OMNIKEY 5427 CK 向卡发送 APDU 命令 的相关文章

随机推荐