通过HID OMNIKEY 5427 CK向卡发送APDU命令 [英] Send APDU command to card through HID OMNIKEY 5427 CK

查看:387
本文介绍了通过HID OMNIKEY 5427 CK向卡发送APDU命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过HID OMNIKEY 5427 CK通过APDUs命令来操作MIFARE卡,即在Windows 10 x64 OS环境上使用WinSCard.dll的Ultralight C卡。 (我在NXP NDA之下,可以完全访问他们的文档。)

I'm trying to pass though APDUs command via HID OMNIKEY 5427 CK to operate MIFARE Card ie. Ultralight C card, on the Windows 10 x64 OS environment using WinSCard.dll. (I'm under NXP NDA and have full access t their documents)

我尝试了几天的在线查找信息。除了两页的手册外,似乎没有该模型的公开文档。

I tried to find information online for days now. Seem like no published document for this model except the 2pages brochure.

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

The simple command like GetUID (FFCA000000) is OK, I can get back the actual card UID.

但是对于用卡进行身份验证,来自HID 5421模型的参考文档说我应该从OpenGenericSession(FFA0000703010001)开始,我尝试这样做,并且读者总是回答6D00h(错误)

But for 'Authentication with Card', reference document from HID 5421 model said I should start with OpenGenericSession (FFA0000703010001), I tried that and reader always replied with 6D00h (error)

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

I tried send Authentication command directly '1Ah+00h' (FFA00005080100F30000641A0000) the reader also always replied with error code.

我有过HID 5421型号的经验,它很简单,不确定为什么5427不同于它的同级产品。

I've experience with HID 5421 model and it quite straight forward, not sure why this 5427 is unlike its sibling.

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

And yes, I contacted HID support. No luck. No useful information I could get from them.

如果有任何想法或有5427软件开发指南,请提供帮助。到目前为止,我已经拉了将近一个星期的头发。

If any one have idea or have 5427 software development guide please help. I'm pulling my hair for almost a week by now.

推荐答案

下面是一个概念验证的Java代码,可用于通信使用Omnikey 5321/6321在通用会话上使用Ultralight-C:

Below is a proof-of-concept java code to communicate with Ultralight-C over Generic Session using 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 Apache Commons Lang

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

Note 2: It has been some time I wrote this code, please validate my thoughts...

注3:有关Ultralight-C身份验证代码,请参见以下伴侣的答案

Note 3: For Ultralight-C authentication code see this companion answer.

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

Generic session example trace for Omnikey 6321 with Ultralight-C (single line arrows denote Generic Session APDUs and double line arrows denote Ultralight-C commands):

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






有些其他说明:


Some additional notes:


  • (AFAIK)此方法在Windows(使用Omnikey驱动程序)下有效。

  • (AFAIK) This approach works under Windows (with Omnikey drivers). It does not work under linux (even with Omnikey drivers).

请注意, PC / SC版本2.02第3部分定义了管理会话透明交换 SWITCH PROTOCOL 命令以标准化的方式提供相同的命令(您的读者可能支持它,而不是专有的通用会话机制-HID甚至参加了

Note that PC/SC version 2.02 Part 3 defines MANAGE SESSION, TRANSAPARENT EXCHANGE and SWITCH PROTOCOL commands which provide the same in a standardized way (your reader might support it instead of proprietary generic session mechanism -- HID even participated on this document).

祝你好运!

这篇关于通过HID OMNIKEY 5427 CK向卡发送APDU命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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