JAVACard API OwnerPIN学习笔记
JAVACard中提供一个OwnerPIN的类用于用户的口令管理,其中主要包括:
check(byte[] pin, short offset, byte length)
reset()
setValidatedFlag(boolean value)
update(byte[] pin, short offset, byte length)
还有个构造器OwnerPIN(byte tryLimit, byte maxPINSize)
。
首先对于构造器:
public OwnerPIN(byte tryLimit, byte maxPINSize)
参数:tryLimit 表示用户最大输入错误的次数,初始化的时候必须大于0;
maxPINSize 表示PIN码的最大长度,必须大于0.
用户PIN码设置方法,调用后会重置PIN剩余尝试次数,同时重置PIN验证标识(即是否通过check):
public void update(byte[] pin, short offset, byte length)
参数:pin
包含PIN码的数组;offset PIN码的偏移量;
length PIN码的长度。
用户PIN验证方法,如果PIN验证通过,且PIN未被锁定(剩余尝试次数为0),将会置PIN验证标识为true,且重置剩余尝试次数到最大值。当验证失败的时候,将会减少剩余尝试次数,当剩余尝试次数为0的时候,PIN将会被锁定。
public boolean check(byte[] pin,
short offset,
byte length)
参数:pin
包含PIN码的数组;offset PIN码的偏移量;
length PIN码的长度。
检查是否通过check方法,获取PIN验证标识:
public boolean isValidated()
当reset卡,或者调用了reset()方法后,PIN验证标识将会重置为false。调用check通过后,
返回true。
如果check方法验证通过后,可以调用reset()重置验证标识至false和剩余尝试次数至最大值。
无需check方法验证通过,可以调用resetAndUnblock()重置验证标识至false和剩余尝试次数至最大值,该方法可以用于PIN被锁定的情况,而reset()方法不能再PIN锁定的情况下使用。
protected boolean getValidatedFlag()以及protected void setValidatedFlag(boolean value)都是protect方法,不做说明,详情可查阅API文档。
下面是自己写的测试demo
package test.pin; import javacard.framework.*; public class testPin extends Applet { byte[] pin6={(byte)0x01,(byte)0x02,(byte)0x03,(byte)0x04,(byte)0x05,(byte)0x06}; byte[] str1={(byte)'d'}; OwnerPIN pin1=new OwnerPIN((byte)0x04,(byte)0x08);; byte[] storeBuffer=new byte[200]; // Account managerAccount=new Account((byte)0x04,(byte)0x08,(byte)0x01); public static void install(byte[] bArray, short bOffset, byte bLength) { new testPin().register(bArray, (short) (bOffset + 1), bArray[bOffset]); } public void testPin() { } public void process(APDU apdu) { if (selectingApplet()) { return; } byte[] buf = apdu.getBuffer(); short readCount = apdu.setIncomingAndReceive(); Util.arrayCopyNonAtomic(buf, (short)0, storeBuffer, (short)0,(short)(readCount+5)); switch (buf[ISO7816.OFFSET_INS]) { case (byte)0x00: checkPin(apdu); break; case (byte)0x01: getTryRemaind(apdu); break; case (byte)0x02: getValidatedFlag(apdu); break; case (byte)0x03: reset(apdu); break; case (byte)0x04: resetAndUnblock(apdu) ; break; case (byte)0x08: pin1.update(pin6,(short)0x00,(byte)0x06); break; default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } } public void reset(APDU apdu) { pin1.reset(); } public void resetAndUnblock(APDU apdu) { pin1.resetAndUnblock(); } public void getValidatedFlag(APDU apdu) { byte[] buf = apdu.getBuffer(); if(pin1.isValidated()) { buf[0]=(byte)0x01; buf[1]=(byte)0x01; } else{ buf[0]=(byte)0x00; buf[1]=(byte)0x00; } apdu.setOutgoingAndSend((short)0,(short)2); } public void checkPin(APDU apdu) { byte[] buf = apdu.getBuffer(); if(pin1.check(storeBuffer,ISO7816.OFFSET_CDATA,storeBuffer[4])) { buf[0]=(byte)0x01; buf[1]=(byte)0x01; } else{ buf[0]=(byte)0x00; buf[1]=(byte)0x00; } apdu.setOutgoingAndSend((short)0,(short)2); } public void getTryRemaind(APDU apdu) { short i=(byte)0x09; byte[] buf = apdu.getBuffer(); buf[0]=pin1.getTriesRemaining(); apdu.setOutgoingAndSend((short)0,(short)1); } }