首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过HID OMNIKEY 5427 CK向卡发送APDU命令

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

Stack Overflow用户
提问于 2017-06-19 12:54:48
回答 1查看 2.5K关注 0票数 7

我正在尝试通过APDUs命令通过HID OMNIKEY 5427 CK来操作MIFARE Card ie。超轻C卡,在使用WinSCard.dll的Windows10 x64 OS环境中。(我在恩智浦保密协议下,对他们的文档具有完全访问权限)

我试着在网上找了好几天的信息。除了2页的宣传册之外,这个模型似乎没有发布过任何文档。

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

但是对于‘卡认证’,参考文档从HID5421型号说我应该从OpenGenericSession (FFA0000703010001)开始,我试过了,读者总是回答6D00h (错误)

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

我有HID 5421型号的经验,它非常简单,不知道为什么5427不像它的兄弟。

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

如果任何人有想法或有5427软件开发指南,请帮助。我已经扯了快一个星期的头发了。

EN

回答 1

Stack Overflow用户

发布于 2017-06-21 02:11:17

下面是用于与Ultralight C进行通信的概念验证java代码

通用会话

使用Omnikey 5321/6321:

代码语言:javascript
复制
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 身份验证代码,请参阅此配套答案。


使用Ultralight-C的Omnikey 6321的通用会话示例跟踪(单线箭头表示通用会话APDU和双线箭头表示Ultralight C命令):

代码语言:javascript
复制
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 Part 3]定义MANAGE SESSION, TRANSAPARENT EXCHANGESWITCH PROTOCOL以标准化的方式提供相同功能的命令(您的读者可能会支持它,而不是专有的通用会话机制-- HID甚至参与了本文档)。

祝你好运!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44622497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档