我刚刚创建了一个非常简单的applet.这是 Java卡技术中的“hello world”.我粘贴了下面的代码.
public class helloworld extends Applet {
private byte[] echoBytes;
private static final short LENGTH_ECHO_BYTES = 256;
/**
* Installs this applet.
*
* @param bArray
* the array containing installation parameters
* @param bOffset
* the starting offset in bArray
* @param bLength
* the length in bytes of the parameter data in bArray
*/
public static void install(byte[] bArray, short bOffset, byte bLength) {
new helloworld();
}
/**
* Only this class's install method should create the applet object.
*/
protected helloworld() {
echoBytes = new byte[LENGTH_ECHO_BYTES];
register();
}
/**
* Processes an incoming APDU.
*
* @see APDU
* @param apdu
* the incoming APDU
*/
@Override
public void process(APDU apdu) {
//Insert your code here
//
byte buffer[] = apdu.getBuffer();
if ((buffer[ISO7816.OFFSET_CLA] == 0) && (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4))){
return;
}
short bytesRead = apdu.setIncomingAndReceive();
short echoOffset = (short) 0;
Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead);
echoOffset += bytesRead;
apdu.setOutgoing();
apdu.setOutgoingLength((short)(echoOffset + 5));
//echo header
apdu.sendBytes((short) 0, (short) 5);
//echo data
apdu.sendBytesLong(echoBytes, (short) 0, echoOffset);
}
}
之后我决定使用Global Platform将它安装在真实卡(J3A081)上,但它失败了.
首先,我检查了卡上是否已安装任何applet并带有命令:
java -jar gp.jar -l
回应是:
AID: A000000003000000 (|........|)
ISD OP_READY: Security Domain, Card lock, Card terminate, Default selected, CVM (PIN) management
当我决定使用* .cap文件安装applet时,我得到了:
java -jar gp.jar -install krystian.cap
javax.smartcardio.CardException: sun.security.smartcardio.PCSCException: Unknown error 0x1f
at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:219)
at sun.security.smartcardio.ChannelImpl.transmit(ChannelImpl.java:90)
at pro.javacard.gp.GlobalPlatform.transmit(GlobalPlatform.java:661)
at pro.javacard.gp.GlobalPlatform.loadCapFile(GlobalPlatform.java:727)
at pro.javacard.gp.GlobalPlatform.loadCapFile(GlobalPlatform.java:686)
at pro.javacard.gp.GPTool.main(GPTool.java:453)
Caused by: sun.security.smartcardio.PCSCException: Unknown error 0x1f
at sun.security.smartcardio.PCSC.SCardTransmit(Native Method)
at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:188)
... 5 more
Exception in thread "main" javax.smartcardio.CardException: sun.security.smartcardio.PCSCException: Unknown error 0x1f
at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:219)
at sun.security.smartcardio.ChannelImpl.transmit(ChannelImpl.java:90)
at pro.javacard.gp.GlobalPlatform.transmit(GlobalPlatform.java:661)
at pro.javacard.gp.GlobalPlatform.loadCapFile(GlobalPlatform.java:727)
at pro.javacard.gp.GlobalPlatform.loadCapFile(GlobalPlatform.java:686)
at pro.javacard.gp.GPTool.main(GPTool.java:453)
Caused by: sun.security.smartcardio.PCSCException: Unknown error 0x1f
at sun.security.smartcardio.PCSC.SCardTransmit(Native Method)
at sun.security.smartcardio.ChannelImpl.doTransmit(ChannelImpl.java:188)
... 5 more
你能告诉我我做错了吗?这张卡是全新的,从未使用过.我正在使用ACR122U NFC读卡器和NXP卡J3A081.
编辑
经过几个小时的尝试,我设法做了几件事.首先,我更新了ACR122U智能卡读卡器的驱动程序.此外,我熟悉GPShell并创建了一个简单的脚本:
mode_211
enable_trace
establish_context
card_connect
select -AID a000000003000000
open_sc -security 1 -keyind 0 -keyver 0 -mac_key 404142434445464748494a4b4c4d4e4f -enc_key 404142434445464748494a4b4c4d4e4f
card_disconnect
release_context
哪个输出:
mode_211
enable_trace
establish_context
card_connect
select -AID a000000003000000
Command --> 00A4040008A000000003000000
Wrapped command --> 00A4040008A000000003000000
Response <-- 6F658408A000000003000000A5599F6501FF9F6E06479100783400734A06072A864 886FC6B01600C060A2A864886FC6B02020101630906072A864886FC6B03640B06092A864886FC6B0 40215650B06092B8510864864020103660C060A2B060104012A026E01029000
open_sc -security 1 -keyind 0 -keyver 0 -mac_key 404142434445464748494a4b4c4d4e4 f -enc_key 404142434445464748494a4b4c4d4e4f
Command --> 80CA006600
Wrapped command --> 80CA006600
Response <-- 664C734A06072A864886FC6B01600C060A2A864886FC6B02020101630906072A864 886FC6B03640B06092A864886FC6B040215650B06092B8510864864020103660C060A2B060104012 A026E01029000
Command --> 805000000853DFBA4B056DAE8800
Wrapped command --> 805000000853DFBA4B056DAE8800
Response <-- 0000510101086197846701020018CC282BD831DB0145313B12DB3E169000
Command --> 84820100103294E6632BFE5E59879A2C9C03EE345E
Wrapped command --> 84820100103294E6632BFE5E59879A2C9C03EE345E
Response <-- 9000
card_disconnect
release_context
所以我想一切正常,但是当我想用这个安装applet时:
mode_211
enable_trace
establish_context
card_connect
select -AID a000000003000000
open_sc -security 1 -keyind 0 -keyver 0 -mac_key 404142434445464748494a4b4c4d4e4f -enc_key 404142434445464748494a4b4c4d4e4f
install -file helloworld.cap -nvDataLimit 2000 -instParam 00 -priv 2
card_disconnect
release_context
我有一个例外:
mode_211 enable_trace establish_context card_connect select -AID a000000003000000 Command --> 00A4040008A000000003000000 Wrapped command --> 00A4040008A000000003000000 Response <-- 6F658408A000000003000000A5599F6501FF9F6E06479100783400734A06072A864 886FC6B01600C060A2A864886FC6B02020101630906072A864886FC6B03640B06092A864886FC6B0 40215650B06092B8510864864020103660C060A2B060104012A026E01029000 open_sc -security 1 -keyind 0 -keyver 0 -mac_key 404142434445464748494a4b4c4d4e4 f -enc_key 404142434445464748494a4b4c4d4e4f Command --> 80CA006600 Wrapped command --> 80CA006600 Response <-- 664C734A06072A864886FC6B01600C060A2A864886FC6B02020101630906072A864 886FC6B03640B06092A864886FC6B040215650B06092B8510864864020103660C060A2B060104012 A026E01029000 Command --> 8050000008ADBD20501C2C87A400 Wrapped command --> 8050000008ADBD20501C2C87A400 Response <-- 0000510101086197846701020019DFABEED157EA9E2F7E75EAA739E89000 Command --> 848201001014781742A86F6C5026B0D999238ABEBA Wrapped command --> 848201001014781742A86F6C5026B0D999238ABEBA Response <-- 9000 install -file helloworld.cap -nvDataLimit 2000 -instParam 00 -priv 2 Command --> 80E602001E07D0D1D2D3D4D50108A000000003000000000AEF08C6020160C80207D0 0000 Wrapped command --> 84E602002607D0D1D2D3D4D50108A000000003000000000AEF08C6020160 C80207D000B9A71938B63B8CFB00 Response <-- 009000 Command --> 80E80000EFC4820157010011DECAFFED010204000107D0D1D2D3D4D50102001F0011 001F000C000B0026000C003B0019000F0000005D00020001000C01010004000B01000107A0000000 62010103000C0108D0D1D2D3D4D50101000C
public class helloworld extends Applet { private byte[] echoBytes; private static final short LENGTH_ECHO_BYTES = 256; /** * Installs this applet. * * @param bArray * the array containing installation parameters * @param bOffset * the starting offset in bArray * @param bLength * the length in bytes of the parameter data in bArray */ public static void install(byte[] bArray, short bOffset, byte bLength) { new helloworld(); } /** * Only this class's install method should create the applet object. */ protected helloworld() { echoBytes = new byte[LENGTH_ECHO_BYTES]; register(); } /** * Processes an incoming APDU. * * @see APDU * @param apdu * the incoming APDU */ @Override public void process(APDU apdu) { //Insert your code here // byte buffer[] = apdu.getBuffer(); if ((buffer[ISO7816.OFFSET_CLA] == 0) && (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4))){ return; } short bytesRead = apdu.setIncomingAndReceive(); short echoOffset = (short) 0; Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead); echoOffset += bytesRead; apdu.setOutgoing(); apdu.setOutgoingLength((short)(echoOffset + 5)); //echo header apdu.sendBytes((short) 0, (short) 5); //echo data apdu.sendBytesLong(echoBytes, (short) 0, echoOffset); } }
C00800300FF0007010000001707003B00011018 8C0000188B00017A02308F00023D8C00033B7A0521198B00042D198B00053B7B0006031A037B0006 928D00073B19037B0006928B00087A08001900020001000103000C48656C6C6F20576F726C642100 0000000500260009068003000380030101000000
public class helloworld extends Applet { private byte[] echoBytes; private static final short LENGTH_ECHO_BYTES = 256; /** * Installs this applet. * * @param bArray * the array containing installation parameters * @param bOffset * the starting offset in bArray * @param bLength * the length in bytes of the parameter data in bArray */ public static void install(byte[] bArray, short bOffset, byte bLength) { new helloworld(); } /** * Only this class's install method should create the applet object. */ protected helloworld() { echoBytes = new byte[LENGTH_ECHO_BYTES]; register(); } /** * Processes an incoming APDU. * * @see APDU * @param apdu * the incoming APDU */ @Override public void process(APDU apdu) { //Insert your code here // byte buffer[] = apdu.getBuffer(); if ((buffer[ISO7816.OFFSET_CLA] == 0) && (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4))){ return; } short bytesRead = apdu.setIncomingAndReceive(); short echoOffset = (short) 0; Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead); echoOffset += bytesRead; apdu.setOutgoing(); apdu.setOutgoingLength((short)(echoOffset + 5)); //echo header apdu.sendBytes((short) 0, (short) 5); //echo data apdu.sendBytesLong(echoBytes, (short) 0, echoOffset); } }
00103800A0103800A060500000006801002 03800A0809000F000000
Wrapped command --> 84E80000F7C4820157010011DECAFFED010204000107D0D1D2D3D4D50102 001F0011001F000C000B0026000C003B0019000F0000005D00020001000C01010004000B01000107 A000000062010103000C0108D0D1D2D3D4D50101000Cpublic class helloworld extends Applet { private byte[] echoBytes; private static final short LENGTH_ECHO_BYTES = 256; /** * Installs this applet. * * @param bArray * the array containing installation parameters * @param bOffset * the starting offset in bArray * @param bLength * the length in bytes of the parameter data in bArray */ public static void install(byte[] bArray, short bOffset, byte bLength) { new helloworld(); } /** * Only this class's install method should create the applet object. */ protected helloworld() { echoBytes = new byte[LENGTH_ECHO_BYTES]; register(); } /** * Processes an incoming APDU. * * @see APDU * @param apdu * the incoming APDU */ @Override public void process(APDU apdu) { //Insert your code here // byte buffer[] = apdu.getBuffer(); if ((buffer[ISO7816.OFFSET_CLA] == 0) && (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4))){ return; } short bytesRead = apdu.setIncomingAndReceive(); short echoOffset = (short) 0; Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead); echoOffset += bytesRead; apdu.setOutgoing(); apdu.setOutgoingLength((short)(echoOffset + 5)); //echo header apdu.sendBytes((short) 0, (short) 5); //echo data apdu.sendBytesLong(echoBytes, (short) 0, echoOffset); } }
C00800300FF0007010000001707003B 000110188C0000188B00017A02308F00023D8C00033B7A0521198B00042D198B00053B7B0006031A 037B0006928D00073B19037B0006928B00087A08001900020001000103000C48656C6C6F20576F72 6C6421000000000500260009068003000380030101000000
public class helloworld extends Applet { private byte[] echoBytes; private static final short LENGTH_ECHO_BYTES = 256; /** * Installs this applet. * * @param bArray * the array containing installation parameters * @param bOffset * the starting offset in bArray * @param bLength * the length in bytes of the parameter data in bArray */ public static void install(byte[] bArray, short bOffset, byte bLength) { new helloworld(); } /** * Only this class's install method should create the applet object. */ protected helloworld() { echoBytes = new byte[LENGTH_ECHO_BYTES]; register(); } /** * Processes an incoming APDU. * * @see APDU * @param apdu * the incoming APDU */ @Override public void process(APDU apdu) { //Insert your code here // byte buffer[] = apdu.getBuffer(); if ((buffer[ISO7816.OFFSET_CLA] == 0) && (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4))){ return; } short bytesRead = apdu.setIncomingAndReceive(); short echoOffset = (short) 0; Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead); echoOffset += bytesRead; apdu.setOutgoing(); apdu.setOutgoingLength((short)(echoOffset + 5)); //echo header apdu.sendBytes((short) 0, (short) 5); //echo data apdu.sendBytesLong(echoBytes, (short) 0, echoOffset); } }
00103800A0103800A0605000000 0680100203800A0809000F00000067CDD7B27E70D011
load() returns 0x0000001F (Urzdzenie doczone do komputera nie dziaa.
任何人都可能有类似的错误吗?你知道它意味着什么吗?
编辑2
我终于设法在我的卡上安装了applet.我使用修改过的GlobalPlatformPro,正如vlp所写,有必要将加载块更改为16个字节.但我只能安装hello world applet,在处理我的时候,GlobalPlatformPro返回异常:
java -jar gp_16byteLoadBlock.jar --install inzynierka.cap pro.javacard.gp.GPException: LOAD failed SW: 6A80 at pro.javacard.gp.GlobalPlatform.check(GlobalPlatform.java:1092) at pro.javacard.gp.GlobalPlatform.loadCapFile(GlobalPlatform.java:728) at pro.javacard.gp.GlobalPlatform.loadCapFile(GlobalPlatform.java:686) at pro.javacard.gp.GPTool.main(GPTool.java:453)
最佳答案 (评论中的讨论记录)
事实证明,ACR122U NFC读卡器存在长APDU的问题(也提到了here).
可能的解决方案之一是以下列方式修改GlobalPlatformPro工具:
>获取来源here
>找到在GlobalPlatform.java:724检索加载文件块的代码部分
>通过用一些较小的常量替换wrapper.getBlockSize()部分来减少加载块大小(确认32工作,确认64不能使用此读取器)
>重新编译GlobalPlatformPro编辑>
最新的GlobalPlatformPro代码adds a -bs选项,允许您设置块大小而无需重新编译.