Hoje explicarei como utilizar o PIN Number (Personal Identification Number), trata-se da velha e conhecida Senha que inserimos ao pagar uma conta no caixa do mercado, sacar dinheiro nos caixas eletronicos, habilitar o SIM Card em um celular, etc.Java Cards possuem seus proprios mecanismos para armazenar e validar PIN's, voce podera utilizar a classe javacard.framework.OwnerPIN para gerenciar todo processo, desde armazenamento, checagem, bloqueio e desbloqueio, ou se preferir podera desenvolver uma classe so sua implementando a Interface javacard.framework.PIN.Vamos ao Codigo: package pin_test;import javacard.framework.*;public class PinTest extends Applet { /** Numero de Tentativas antes do Bloqueio */ static private final byte TRY_LIMIT = 0x03; /** Tamanho Maximo do PIN (16 Caracteres) */ static private final byte MAX_PIN_SIZE = 0x10; /** Instrucao para Definicao do PIN */ static private final byte INS_UPDATE_PIN = (byte)0x02; /** Instrucao para Validacao do PIN */ static private final byte INS_CHECK_PIN = (byte)0x04; /** Instrucao que Verifica o PIN foi autenticado */ static private final byte INS_IS_VALIDATE = (byte)0x06; /** Instrucao que Reseta uma Autenticacao */ static private final byte INS_RESET_PIN = (byte)0x08; /** Instrucao para Desbloqueio do PIN */ static private final byte INS_UNLOCK_PIN = (byte)0x0A; /** Instrucao que retorna quantidades de Tentativas */ static private final byte INS_GET_REMAIN = (byte)0x0C; /** PIN Number */ private OwnerPIN pin; /** * Construtor */ private PinTest() { //Objeto Persistente this.pin = new OwnerPIN( TRY_LIMIT, MAX_PIN_SIZE ); } /** * Installer * @param bArray * @param bOffset * @param bLength * @throws ISOException */ public static void install (byte bArray[], short bOffset, byte bLength) throws ISOException{ new PinTest().register(); } /** * Processa APDU */ public void process(APDU apdu){ //Acquire Reference IN/OUT byte buffer[] = apdu.getBuffer(); //On Select if (selectingApplet()) ISOException.throwIt(ISO7816.SW_NO_ERROR); switch ( buffer[ISO7816.OFFSET_INS] ){ //Define um PIN Number case INS_UPDATE_PIN : { //Adquire tamanho do novo PIN byte pinLen = (byte)apdu.setIncomingAndReceive(); if ( pinLen < (byte)1 || pinLen > MAX_PIN_SIZE ) ISOException.throwIt(ISO7816.SW_DATA_INVALID); //Redefine PIN pin.update(buffer, ISO7816.OFFSET_CDATA, pinLen); ISOException.throwIt(ISO7816.SW_NO_ERROR); } //Autentica um PIN case INS_CHECK_PIN : { //Adquire tamanho do PIN byte pinLen = (byte)apdu.setIncomingAndReceive(); if ( pinLen < (byte)1 ) ISOException.throwIt(ISO7816.SW_DATA_INVALID); //Checa PIN if ( !pin.check(buffer, ISO7816.OFFSET_CDATA, pinLen) ) ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); ISOException.throwIt(ISO7816.SW_NO_ERROR); } //Verifica se Autenticado case INS_IS_VALIDATE : { //Verifica Validade do PIN if ( pin.isValidated() ) ISOException.throwIt(ISO7816.SW_NO_ERROR); else ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } //Reseta Autenticacao case INS_RESET_PIN : { pin.reset(); ISOException.throwIt(ISO7816.SW_NO_ERROR); } //Desbloqueia um PIN case INS_UNLOCK_PIN : { pin.resetAndUnblock(); ISOException.throwIt(ISO7816.SW_NO_ERROR); } //Adquire Quantidades de Erros Remanescentes case INS_GET_REMAIN : { buffer[0] = pin.getTriesRemaining(); apdu.setOutgoing(); apdu.setOutgoingLength((short)1); apdu.sendBytes((short)0, (short)1); ISOException.throwIt(ISO7816.SW_NO_ERROR); } }//switch end //Instrucao Desconhecida ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); }}Na Linha 62, iniciamos ou definimos um PIN number, o metodo update tambem reseta a quantidade de tentativas do PIN, voce pode testar isso com o seguinte APDU:0x00 0x02 0x00 0x00 0x05 0x01 0x02 0x03 0x04 0x05 (0x7F - Caso esteja no JCWDE).Esse APDU cria um PIN de 5 numeros "12345".Na Linha 76 validamos um PIN, esse procedimento tambem e conhecido como "Match on Card", pois uma vez definido o PIN ele nunca e exposto e a validacao e realizada internamente pelo cartao, utilize o seguinte APDU para testar:0x00 0x04 0x00 0x00 0x05 0x01 0x02 0x03 0x04 0x05