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

7
我想通过HID OMNIKEY 5427 CK将APDU命令传递到WinSCard.dll,以便在Windows 10 x64操作系统环境下操作MIFARE卡(如Ultralight C卡)。但是我找了几天的在线信息,似乎除了两页的手册外,没有关于这个型号的其它发表文献。简单的命令如GetUID(FFCA000000)没问题,我可以得到实际的卡片UID。但是对于“与卡的认证”,来自HID 5421型号的参考文档说我应该从OpenGenericSession(FFA0000703010001)开始,我尝试了这个命令,但读卡器总是回复6D00h(错误)。我还试图直接发送认证命令'1Ah+00h'(FFA00005080100F30000641A0000),读卡器也总是回复错误代码。我有使用HID 5421型号的经验,它很简单明了,不知道为什么这个5427型号不像它的兄弟那样。是的,我联系过HID支持,但没有结果。如果有人有想法或者有5427软件开发指南,请帮忙,现在我已经抓狂了一个星期。

1
我可以分享一个可用的代码,以访问使用通用会话的HID 5321/6321读卡器的Ultralight-C -- 但似乎您的问题与HID 5427读卡器有关(我无法访问)。通用会话的有趣之处在于它可以从Windows工作,但在Linux上不行(即使使用官方omnikey驱动程序)。值得一试的是检查5427是否使用与5421相同的驱动程序...祝好运! - vlp
我的目标平台是Windows,所以我希望能够使用通用会话方法。请分享代码,我认为所有HID设备之间的通用会话协议都是相同的,但我找不到在线演示该功能的HID示例。对我来说奇怪的是,这个特定型号5427没有任何在线开发指南。非常感谢您的编辑和慷慨。@vlp - Eric F.
1
你知道可以通过Web界面配置OK5427CK吗?也许你会在那里找到缺失的设置。 - arminb
1
是的,OK5427CK是一个复合USB设备(智能卡读卡器+以太网接口)。您需要安装OMNIKEY驱动程序以支持OK5427CK,否则默认的Windows驱动程序将无法正常工作。然后,在设备管理器中,您将看到一个额外的“网络接口”,并且在您的网络连接中也会出现。您应该能够通过http://192.168.63.99调用其接口(请参见第2章,链接:goo.gl/hjj7Ut)。不幸的是,Web界面驱动程序仅适用于Windows 7及以下版本。 - arminb
无论如何,@arminb,你知道这个OK5427CK的OpenGenericSession APDU命令是什么吗?我认为这是访问我真正需要的所有APDU功能的关键。 - Eric F.
显示剩余4条评论
1个回答

2
以下是一个与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.smartcardioApache Commons Lang
注意2:我写这段代码已经有一段时间了,请验证我的想法...
注意3:有关Ultralight-C身份验证代码,请参阅此伴随答案
Omnikey 6321与Ultralight-C的通用会话示例跟踪(单线箭头表示通用会话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

一些额外的注释:
  • (据我所知)这种方法适用于Windows(使用Omnikey驱动程序)。它在Linux下不起作用(即使使用Omnikey驱动程序也不行)。

  • 请注意,PC / SC版本2.02第3部分定义了MANAGE SESSIONTRANSAPARENT EXCHANGESWITCH PROTOCOL命令,以标准化的方式提供相同的功能(你的读者可能支持它而不是专有的通用会话机制——HID甚至参与了这个文档)。

祝你好运!

非常感谢。这段代码让我受益匪浅。不幸的是,OpenGeneric会话APDU对于5427仍然无法使用。总是向我返回6D00。我将继续研究您提供的PC/SC版本2.02第3部分规范,看起来很有前途。 - Eric F.
1
@EricF.:你有没有得到5427的解决方案?能否请分享一下? - SK.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接