无法删除Java卡小程序
我对Java卡很陌生,但经过一些阅读,我的第一个小程序工作得很好……直到今天。我进行了一些重构,并在Applet中插入了一个OwnerPIN对象。现在我可以编写一次小程序,但第二次,删除不再有效。 以下是我的输出:无法删除Java卡小程序,java,applet,javacard,Java,Applet,Javacard,我对Java卡很陌生,但经过一些阅读,我的第一个小程序工作得很好……直到今天。我进行了一些重构,并在Applet中插入了一个OwnerPIN对象。现在我可以编写一次小程序,但第二次,删除不再有效。 以下是我的输出: Java Card 2.2.2 Class File Converter, Version 1.3 Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms.
Java Card 2.2.2 Class File Converter, Version 1.3
Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms.
mode_201
gemXpressoPro
enable_timer
establish_context
command time: 16 ms
card_connect
command time: 187 ms
select -AID A000000018434D00
command time: 78 ms
open_sc -security 1 -keyind 0 -keyver 0 -key 47454d5850524553534f53414d504c45 -keyDerivation visa2
command time: 328 ms
delete -AID 0102030405060708090000
delete() returns 0x80206985 (6985: Command not allowed - Conditions of use not satisfied.)
command time: 31 ms
delete -AID 01020304050607080900
delete() returns 0x80206985 (6985: Command not allowed - Conditions of use not satisfied.)
command time: 47 ms
get_status -element e0
List of applets (AID state privileges)
a000000018434d00 1 9e
a0000000620001 1 0
a0000000620002 1 0
a0000000620003 1 0
a0000000620101 1 0
a000000062010101 1 0
a0000000620102 1 0
a0000000620201 1 0
a0000000620209 1 0
a0000000620202 1 0
a000000018100109 1 0
a00000001810010b 1 0
a00000001810010a 1 0
a0000000030000 1 0
a000000018100106 1 0
a000000018100201 1 0
a000000018100101 1 0
a00000015100 1 0
a000000018100108 1 0
a0000000181001ff 1 0
a000000018100501 1 0
a000000018100502 1 0
a000000018100401 1 0
5365637572697479 1 0
a0000000035350 1 0
01020304050607080900 1 0
0102030405060708090000 7 0
command time: 187 ms
install -file mycap.cap -sdAID A000000018434D00 -nvCodeLimit 4096 -instParam 2265
install_for_load() returns 0x80206985 (6985: Command not allowed - Conditions of use not satisfied.)
更新
根据要求,我的部分代码:
public class MyApplet extends Applet
{
private static final byte MY_CLA = (byte)0xB0;
...
private final static byte VERIFY_INS = (byte)0x40;
...
private final static byte NEED_VERIFICATION_INS = (byte)0x47;
private final static byte GET_INSTALL_PARAMS_INS = (byte)0x50;
private final static byte GET_REMAINING_PIN_TRIES_INS = (byte)0x60;
private final static byte PIN_TRY_LIMIT = (byte)0x03;
private final static byte MAX_PIN_SIZE = (byte)0x08;
// signal that the PIN verification failed
private final static short SW_VERIFICATION_FAILED = 0x6300;
private final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301;
...
private static byte[] testdata;
private OwnerPIN m_pin;
private byte[] m_array;
private short m_offset;
private byte m_length;
private MyApplet(byte[] bArray, short bOffset, byte bLength)
{
...
m_pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
// m_array = bArray;
// m_offset = bOffset;
// m_length = bLength;
register();
}
public boolean select()
{
if (m_pin.getTriesRemaining() == 0)
{
return false;
}
return true;
}
public void deselect()
{
m_pin.resetAndUnblock();
}
private void adminRest()
{
m_pin.resetAndUnblock();
return;
}
private void getInstallParams(APDU apdu)
{
try
{
byte[] buffer = apdu.getBuffer();
// inform the JCRE that the applet has data to return
short le = apdu.setOutgoing();
// set the actual number of the outgoing data bytes
apdu.setOutgoingLength(((short)testdata.length));
apdu.sendBytesLong(testdata, (short)0, (short)testdata.length);
}
catch (APDUException e)
{
// TODO Auto-generated catch block
}
catch (TransactionException e)
{
// TODO Auto-generated catch block
}
catch (ArrayIndexOutOfBoundsException e)
{
// TODO Auto-generated catch block
}
catch (NullPointerException e)
{
// TODO Auto-generated catch block
}
}
/**
* Get number of remaining pin tries
*
* @param apdu
*/
private void getPinTriesRemaining(APDU apdu)
{
try
{
byte[] buffer = apdu.getBuffer();
// inform the JCRE that the applet has data to return
apdu.setOutgoing();
// set the actual number of the outgoing data bytes
apdu.setOutgoingLength((byte)2);
// write the PinTriesRemaining into the APDU buffer at the offset 0
Util.setShort(buffer, (short)0, m_pin.getTriesRemaining());
// send the 2-byte balance at the offset
// 0 in the apdu buffer
apdu.sendBytes((short)0, (short)2);
}
catch (APDUException e)
{
// TODO Auto-generated catch block
}
catch (TransactionException e)
{
// TODO Auto-generated catch block
}
catch (ArrayIndexOutOfBoundsException e)
{
// TODO Auto-generated catch block
}
catch (NullPointerException e)
{
// TODO Auto-generated catch block
}
} // end of getPinTriesRemaining method
/**
* Verification method to verify the PIN
*
* @param apdu
*/
private void verify(APDU apdu)
{
byte[] buffer = apdu.getBuffer();
// receive the PIN data for validation.
byte byteRead = (byte)(apdu.setIncomingAndReceive());
// check pin
// the PIN data is read into the APDU buffer
// starting at the offset ISO7816.OFFSET_CDATA
// the PIN data length = byteRead
if (!m_pin.check(buffer, ISO7816.OFFSET_CDATA, byteRead))
{
ISOException.throwIt(SW_VERIFICATION_FAILED);
}
} // end of verify method
/**
* Installs the applet.
*
* @param bArray array with installation parameters.
* @param bOffset offset into array.
* @param bLength the length of the parameters.
*/
public static void install(byte[] bArray, short bOffset, byte bLength)
{
testdata = new byte[bLength];
Util.arrayCopy(bArray, (short)0, testdata, (short)0, bLength);
new MyApplet(bArray, bOffset, bLength);
}
/**
* Processes an incoming APDU.
*
* @param apdu the APDU.
*/
public void process(APDU apdu)
{
byte l_transferredBuffer[] = apdu.getBuffer();
// Get the CLA; mask out the logical-channel info.
l_transferredBuffer[ISO7816.OFFSET_CLA] = (byte)(l_transferredBuffer[ISO7816.OFFSET_CLA] & (byte)0xFC);
if ((l_transferredBuffer[ISO7816.OFFSET_CLA] == 0) && (l_transferredBuffer[ISO7816.OFFSET_INS] == (byte)(0xA4)))
{
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
if (l_transferredBuffer[ISO7816.OFFSET_CLA] != MY_CLA)
{
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
byte l_ins = l_transferredBuffer[ISO7816.OFFSET_INS];
...
else if (l_ins == VERIFY_INS)
{
verify(apdu);
}
...
else if (l_ins == NEED_VERIFICATION_INS)
{
isNeedVerification(apdu, l_transferredBuffer);
}
else if (l_ins == GET_INSTALL_PARAMS_INS)
{
getInstallParams(apdu);
}
else if (l_ins == GET_REMAINING_PIN_TRIES_INS)
{
getPinTriesRemaining(apdu);
}
else
{
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
private void isNeedVerification(APDU apdu, byte[] buffer)
{
// The structure for the response request is
// ---------------------
// | response |
// | 1 byte |
// ---------------------
getRequest(apdu, buffer);
byte[] l_needVerificationResponse = new byte[1];
boolean l_validated = m_pin.isValidated();
if (l_validated)
{
l_needVerificationResponse[0] = 1;
}
else
{
l_needVerificationResponse[0] = 0;
}
apdu.setOutgoing();
apdu.setOutgoingLength((short)l_needVerificationResponse.length);
apdu.sendBytesLong(l_needVerificationResponse, (short)0, (short)l_needVerificationResponse.length);
}
private byte[] getRequest(APDU apdu, byte[] transferredBuffer)
{
short l_setIncomingAndReceive = apdu.setIncomingAndReceive();
byte[] request = new byte[l_setIncomingAndReceive];
for (short i = 0; i < request.length; i++)
{
short l_j = (short)(ISO7816.OFFSET_CDATA + i);
request[i] = transferredBuffer[l_j];
}
return request;
}
...
}
公共类MyApplet扩展Applet
{
私有静态最终字节MY_CLA=(字节)0xB0;
...
私有最终静态字节验证_INS=(字节)0x40;
...
私有最终静态字节需要\u验证\u INS=(字节)0x47;
私有最终静态字节GET_INSTALL_PARAMS_INS=(字节)0x50;
私有最终静态字节GET_剩余_引脚_尝试_INS=(字节)0x60;
私有最终静态字节PIN\u TRY\u LIMIT=(字节)0x03;
私有最终静态字节MAX_PIN_SIZE=(字节)0x08;
//PIN验证失败的信号
专用最终静态短路开关验证失败=0x6300;
专用最终静态短路开关引脚验证要求=0x6301;
...
私有静态字节[]testdata;
私人业主潘文彬;
专用字节[]m_数组;
私人短m_抵消;
专用字节m_长度;
私有MyApplet(字节[]bArray,短bOffset,字节bLength)
{
...
m_pin=新所有者pin(pin_TRY_LIMIT,MAX_pin_SIZE);
//m_阵列=bArray;
//m_offset=bOffset;
//m_长度=稠度;
寄存器();
}
公共布尔选择()
{
if(m_pin.getTriesRemaining()==0)
{
返回false;
}
返回true;
}
公共无效取消选择()
{
m_pin.resetAndUnblock();
}
私有void adminRest()
{
m_pin.resetAndUnblock();
返回;
}
私有void getInstallParams(APDU APDU)
{
尝试
{
byte[]buffer=apdu.getBuffer();
//通知JCRE小程序有数据要返回
short le=apdu.setOutgoing();
//设置传出数据字节的实际数目
apdu.setOutgoingLength(((short)testdata.length));
apdu.sendBytesLong(testdata,(short)0,(short)testdata.length);
}
捕获(APDUException e)
{
//TODO自动生成的捕捉块
}
捕获(TransactionException e)
{
//TODO自动生成的捕捉块
}
捕获(阵列索引边界外异常e)
{
//TODO自动生成的捕捉块
}
捕获(NullPointerException e)
{
//TODO自动生成的捕捉块
}
}
/**
*获取剩余pin尝试次数
*
*@param apdu
*/
私有void getPinTriesRemaining(APDU APDU)
{
尝试
{
byte[]buffer=apdu.getBuffer();
//通知JCRE小程序有数据要返回
apdu.setOutgoing();
//设置传出数据字节的实际数目
apdu.setOutgoingLength((字节)2);
//在偏移量0处将PintriesMaining写入APDU缓冲区
Util.setShort(buffer,(short)0,m_pin.getTriesRemaining();
//发送偏移处的2字节余额
//apdu缓冲区中的0
apdu.sendBytes((短)0,(短)2);
}
捕获(APDUException e)
{
//TODO自动生成的捕捉块
}
捕获(TransactionException e)
{
//TODO自动生成的捕捉块
}
捕获(阵列索引边界外异常e)
{
//TODO自动生成的捕捉块
}
捕获(NullPointerException e)
{
//TODO自动生成的捕捉块
}
}//GetPintriesMaining方法的结束
/**
*验证销的验证方法
*
*@param apdu
*/
私有无效验证(APDU APDU)
{
byte[]buffer=apdu.getBuffer();
//接收PIN数据以进行验证。
byte byteRead=(byte)(apdu.setIncomingAndReceive());
//别针
//引脚数据被读入APDU缓冲区
//从偏移量ISO7816.offset\U CDATA开始
//引脚数据长度=字节数
如果(!m_pin.check(缓冲区,ISO7816.OFFSET\u CDATA,字节))
{
ISOException.throwIt(软件验证失败);
}
}//验证方法结束
/**
*安装小程序。
*
*@param bArray阵列,带有安装参数。
*@param bOffset偏移到数组中。
*@param bLength参数的长度。
*/
公共静态无效安装(字节[]bArray,短bOffset,字节bLength)
{
testdata=新字节[bLength];
Util.arrayCopy(baray,(short)0,testdata,(short)0,bLength);
新的MyApplet(bArray、bOffset、bLength);
}
/**
*处理传入的APDU。
*
*@param apdu这个apdu。
*/
公共作废流程(APDU APDU)
{
字节l_transferredBuffer[]=apdu.getBuffer();
//获取CLA;屏蔽逻辑通道信息。
l_transferredBuffer[ISO7816.OFFSET_CLA]=(字节)(l_transferredBuffer[ISO7816.OFFSET_CLA]&(字节)0xFC);
if((l_transferredBuffer[ISO7816.OFFSET\u CLA]==0)和&(l_transferredBuffer[ISO7816.OFFSET\u INS]==(字节)(0xA4)))
{
ISOException.throwIt(不支持ISO7816.SW_CLA_);
}
if(l_transferredBuffer[ISO7816.OFFSET_CLA]!=MY_CLA)
{
ISOException.throwIt(不支持ISO7816.SW_CLA_);
}
字节l_ins=l_transferredBuffer[ISO7816.OFFSET_ins];
...
else if(l_ins==验证_ins)
{
验证(apdu);
}
...
else if(l_ins==需要验证)
{
isNeedVerification(apdu、l_transferredBuffer);
}
else if(l_ins==获取安装参数)
{
getInstallParams(apdu);
}
private static byte[] testdata;
public final class MyApplet extends Applet implements AppletEvent {
private static byte[] testdata;
...
//This method is called in the moment of uninstallation
public final void uninstall() {
testData = null; //release the reference --> testData can be GC
}
...
}
G:\BasicTestTools\SmartCardTools>gp -key 404142434445464748494a4b4c4d4e4f -list
AID: A000000151000000 (|....Q...|)
ISD OP_READY: Security Domain, Card lock, Card terminate, Default selected, CVM (PIN) management
AID: 010203040503 (|......|)
App SELECTABLE: (none)
AID: A0000001515350 (|....QSP|)
ExM LOADED: (none)
A000000151535041 (|....QSPA|)
AID: 0102030405 (|.....|)
ExM LOADED: (none)
010203040503 (|......|)
G:\BasicTestTools\SmartCardTools>gp -key 404142434445464748494a4b4c4d4e4f -delete 0102030405
Could not delete AID: 0102030405
TIP: Maybe try with --deletedeps
pro.javacard.gp.GPException: Deletion failed SW: 6985
at pro.javacard.gp.GlobalPlatform.check(GlobalPlatform.java:1092)
at pro.javacard.gp.GlobalPlatform.deleteAID(GlobalPlatform.java:867)
at pro.javacard.gp.GPTool.main(GPTool.java:390)
G:\BasicTestTools\SmartCardTools>gp -key 404142434445464748494a4b4c4d4e4f -delete 0102030405 -deletedeps
G:\BasicTestTools\SmartCardTools>gp -key 404142434445464748494a4b4c4d4e4f -list
AID: A000000151000000 (|....Q...|)
ISD OP_READY: Security Domain, Card lock, Card terminate, Default selected, CVM (PIN) management
AID: A0000001515350 (|....QSP|)
ExM LOADED: (none)
A000000151535041 (|....QSPA|)
G:\BasicTestTools\SmartCardTools>gp -key 404142434445464748494a4b4c4d4e4f -install C:\NetBeansProjects\test2\dist\test2.cap
G:\BasicTestTools\SmartCardTools>gp -key 404142434445464748494a4b4c4d4e4f -list
AID: A000000151000000 (|....Q...|)
ISD OP_READY: Security Domain, Card lock, Card terminate, Default selected, CVM (PIN) management
AID: 010203040503 (|......|)
App SELECTABLE: (none)
AID: A0000001515350 (|....QSP|)
ExM LOADED: (none)
A000000151535041 (|....QSPA|)
AID: 0102030405 (|.....|)
ExM LOADED: (none)
010203040503 (|......|)
G:\BasicTestTools\SmartCardTools>gp -key 00112233445566778899aabbccddeeff -list
pro.javacard.gp.GPException: STRICT WARNING: Card cryptogram invalid!
Card: 7F9CFF3D61110EF2
Host: 9EE2CDBF4A088053
!!! DO NOT RE-TRY THE SAME COMMAND/KEYS OR YOU MAY BRICK YOUR CARD !!!
at pro.javacard.gp.GlobalPlatform.printStrictWarning(GlobalPlatform.java:184)
at pro.javacard.gp.GlobalPlatform.openSecureChannel(GlobalPlatform.java:515)
at pro.javacard.gp.GPTool.main(GPTool.java:371)