⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 javapursecrypto.java

📁 一个javacard的身份验证程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                apdu.setOutgoingAndSend((short)0, offset);    }        /**     * Handles Initialize Transaction APDU.     * <p>See <em>Java Card 2.1 Reference Implementation User's Guide</em> for details.     *     * @param apdu APDU object     */    private void processInitializeTransaction(APDU apdu) {        if (transientBools[TRANSACTION_INITIALIZED])            ISOException.throwIt(SW_COMMAND_OUT_OF_SEQUENCE);        if (!userPIN.isValidated())            ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);        byte[] buffer = apdu.getBuffer();        if (buffer[ISO7816.OFFSET_LC] != LC_IT)            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);        if (buffer[ISO7816.OFFSET_P2] != 0)            ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);        apdu.setIncomingAndReceive();    // get expected data        byte transactionType = buffer[ISO7816.OFFSET_P1];        transientShorts[TRANSACTION_TYPE_IX] = transactionType;        short amount = Util.getShort(buffer, ISO7816.OFFSET_CDATA);        transientShorts[AMOUNT_IX] = amount;                short balance = checkTransactionValues(transactionType, amount);                // Increment TN in Transient Memory & compute signature        short newTN = (short)(TN + 1);        transientShorts[TN_IX] = newTN;        Util.arrayCopyNonAtomic(buffer, CAD_ID_OFFSET, CAD_ID_array, START, ID_LENGTH);                // Send	R-APDU        short offset = Util.arrayCopyNonAtomic(ID_Purse, START, buffer, START, ID_LENGTH);        offset = Util.arrayCopyNonAtomic(ExpDate, START, buffer, offset, DATE_LENGTH);        offset = Util.setShort(buffer, offset, balance);        offset = Util.setShort(buffer, offset, newTN);        // The crypto processing could be done here        deskey.setKey(keyData, (short)0);        sig.init(deskey, Signature.MODE_SIGN);        short sigLength = sig.sign(buffer, START, (short)(offset - START),             byteArray8, (short)0);        offset = Util.arrayCopyNonAtomic(byteArray8, START, buffer, offset, SIGNATURE_LENGTH);                apdu.setOutgoingAndSend(START, (short)(offset - START));        transientBools[TRANSACTION_INITIALIZED] = true;    }        /**     * Handles Complete Transaction APDU.     * @param apdu APDU object     */    private void processCompleteTransaction(APDU apdu) {        if (!transientBools[TRANSACTION_INITIALIZED])            ISOException.throwIt(SW_COMMAND_OUT_OF_SEQUENCE);        byte[] buffer = apdu.getBuffer();        if (buffer[ISO7816.OFFSET_LC] != LC_CT)            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);        if ((buffer[ISO7816.OFFSET_P1] != 0) || (buffer[ISO7816.OFFSET_P2] != 0))            ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);                apdu.setIncomingAndReceive();    // get expected data                //restore transaction data from transient        short newTN = transientShorts[TN_IX];        short amount = transientShorts[AMOUNT_IX];        short newBalance = transientShorts[NEW_BALANCE_IX];        //The signature verification         //get CLA, INS, P1, P2, LC        short offset = Util.arrayCopyNonAtomic(buffer, (short)0, MAC_buffer,(byte)0, (short)5);        Util.arrayCopyNonAtomic(buffer, offset, byteArray8,(byte)0, SIGNATURE_LENGTH);        Util.arrayCopyNonAtomic(buffer, (short)(offset + SIGNATURE_LENGTH), MAC_buffer,(byte)5, (short)DATETIME_LENGTH);        deskey.setKey(keyData, (short)0);        sig.init(deskey, Signature.MODE_VERIFY);        boolean signatureOK = sig.verify(MAC_buffer, (short)0, (short)10,            byteArray8, START, SIGNATURE_LENGTH);                //prepare transaction record in APDU buffer        offset = Util.setShort(buffer, START, newTN);        buffer[offset] = (byte)transientShorts[TRANSACTION_TYPE_IX];        offset++;        offset = Util.setShort(buffer, offset, amount);        //CAD ID was left in this array from Initialize Transaction        offset = Util.arrayCopyNonAtomic(CAD_ID_array, START, buffer, offset, ID_LENGTH);                //Date and time are copied in APDU buffer to where they should go        //in the transaction record.        short balanceOffset = offset =            Util.arrayCopyNonAtomic(buffer, (short)(ISO7816.OFFSET_CDATA + 8),             buffer, offset, DATETIME_LENGTH);        //Balance and SW will be added to transactionRecord	later        if (!signatureOK) {            //Branch for unsuccessful transaction. Balance is not updated,            //otherwise transactionLog is recorded the same way as in successful transaction            offset = Util.setShort(buffer, offset, transientShorts[CURRENT_BALANCE_IX]); // old balance            Util.setShort(buffer, offset, SW_WRONG_SIGNATURE);            //done with preparing transaction record                        byte[] theRecord = transactionLogFile.getNewLogRecord();            //The following	few	steps have to be performed atomically!            JCSystem.beginTransaction();            TN = newTN;            Util.arrayCopy(buffer, START,                 theRecord, START, TRANSACTION_RECORD_LENGTH);            transactionLogFile.updateNewLogRecord();            JCSystem.commitTransaction();                        //Now we can throw exception            transientBools[TRANSACTION_INITIALIZED] = false;            ISOException.throwIt(SW_WRONG_SIGNATURE);        } else {            //Branch for successful transaction.            offset = Util.setShort(buffer, offset, transientShorts[NEW_BALANCE_IX]);            Util.setShort(buffer, offset, ISO7816.SW_NO_ERROR);            // done with preparing transaction record                        byte[] theRecord = transactionLogFile.getNewLogRecord();            //The following few steps have to be performed atomically!            JCSystem.beginTransaction();            TN = transientShorts[TN_IX];            //Update balance            Util.setShort(balancesRecord, START, newBalance);            Util.arrayCopy(buffer, START,                 theRecord, START, TRANSACTION_RECORD_LENGTH);            transactionLogFile.updateNewLogRecord();            JCSystem.commitTransaction();        }                // Do loyalty work        // We have all the information in the buffer, the loyalty applets shouldn't        // know transaction number and the balance of purse - so we zero out these        // fields first        Util.setShort(buffer, START, (short)0);        Util.setShort(buffer, balanceOffset, (short)0);        short loyaltyCADValue = Util.getShort(CAD_ID_array, START);        for (byte loyaltyIndex = 0; loyaltyIndex < MAX_LOYALTY; loyaltyIndex++) {            if (loyaltyCAD[loyaltyIndex] == loyaltyCADValue) {                loyaltySIO[loyaltyIndex].grantPoints (buffer);                break;            }        }                offset = Util.setShort(MAC_buffer, START, newBalance);        Util.setShort(MAC_buffer, offset, SW_SUCCESS);        deskey.setKey(keyData, (short)0);        sig.init(deskey, Signature.MODE_SIGN);        short sigLength = sig.sign(MAC_buffer, (short)0, (short)4,             byteArray8, (short)0);                //send R-APDU        offset = Util.setShort(buffer, START, newBalance);        offset = Util.arrayCopyNonAtomic(byteArray8, START, buffer, offset, SIGNATURE_LENGTH);        apdu.setOutgoingAndSend(START, (short)(offset - START));                transientBools[TRANSACTION_INITIALIZED] = false;    }            /**     * Handles Initialize Parameter Update APDU.     *     * <p><em>NOTE:</em> In this sample implementation we assume that all the     * Parameter Updates are performed in somewhat secured facility and therefore     * the tearing of the card is not an issue. That's why we don't do any     * transactional protection while processing Initialize and Complete     * Parameter Update APDU commands.     *     * @param apdu APDU object     */    private void processInitializeUpdate(APDU apdu) {        if (transientBools[UPDATE_INITIALIZED])            ISOException.throwIt(SW_COMMAND_OUT_OF_SEQUENCE);        if (!masterPIN.isValidated() && isPersonalized)            ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);                byte[] buffer = apdu.getBuffer();        if ((buffer[ISO7816.OFFSET_P1] != 0) || (buffer[ISO7816.OFFSET_P2] != 0))            ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);                // Because this is a case 2 command (outgoing data only), the contents of P3        //  are undefined. In T=0, P3 is Le. In T=1, P3 is Lc. Therefore, we don't        //  bother to test the contents of buffer[ISO7816.OFFSET_LC].                        PUN++; //Increment parameter Update Number                // Send R-APDU        short offset = Util.arrayCopyNonAtomic(ID_Purse, START, buffer, START, ID_LENGTH);        offset = Util.arrayCopyNonAtomic(ExpDate, START, buffer, offset, DATE_LENGTH);        offset = Util.setShort(buffer, offset, PUN);        apdu.setOutgoingAndSend(START, (short)(offset - START));                transientBools[UPDATE_INITIALIZED] = true;    }        /**     * Handles Complete Parameter Update APDU.     * @param apdu APDU object     */    private void processCompleteUpdate(APDU apdu) {        if (!transientBools[UPDATE_INITIALIZED])            ISOException.throwIt(SW_COMMAND_OUT_OF_SEQUENCE);        byte[] buffer = apdu.getBuffer();        if ((buffer[ISO7816.OFFSET_P1] != 0) || (buffer[ISO7816.OFFSET_P2] != 0))            ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);        short count = apdu.setIncomingAndReceive();    // get expected data        byte lc = buffer[ISO7816.OFFSET_LC];        //The signature verification         //get CLA, INS, P1, P2, LC        //message to sign length        short messageLength = (short)(lc - SIGNATURE_LENGTH + 5);        short offset = Util.arrayCopyNonAtomic(buffer, (short)0, MAC_buffer,(byte)0, (short)messageLength);        offset = Util.arrayCopyNonAtomic(buffer, offset, byteArray8,(byte)0, SIGNATURE_LENGTH);         // verify signature if in coming apdu        deskey.setKey(keyData, (short)0);        sig.init(deskey, Signature.MODE_VERIFY);        boolean signatureOK = sig.verify(MAC_buffer, (short)0, messageLength,            byteArray8, START, SIGNATURE_LENGTH);                    if (!signatureOK)            ISOException.throwIt(SW_WRONG_SIGNATURE);                switch (buffer[TLV_OFFSET]) {        case MASTER_PIN_UPDATE:            updatePIN(apdu, masterPIN);            setIsPersonalized();            break;        case USER_PIN_UPDATE:            updatePIN(apdu, userPIN);            break;        case EXP_DATE_UPDATE:            updateParameterValue(apdu, ExpDate);            break;        case PURSE_ID_UPDATE:            updateParameterValue(apdu, ID_Purse);            break;        case MAX_BAL_UPDATE:            updateBalanceValue(apdu, OFFSET_BAL_MAX);            break;        case MAX_M_UPDATE:            updateBalanceValue(apdu, OFFSET_AMOUNT_MAX);            break;        case VERSION_UPDATE:            updateParametersFile(apdu);            break;        case LOYALTY1_UPDATE:            updateLoyaltyProgram(apdu, (byte)0);            break;        case LOYALTY2_UPDATE:            updateLoyaltyProgram(apdu, (byte)1);            break;        case LOYALTY3_UPDATE:            updateLoyaltyProgram(apdu, (byte)2);            break;        case LOYALTY4_UPDATE:            updateLoyaltyProgram(apdu, (byte)3);            break;        default:            ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);        }                //sign the return message        //Admittedly, this is a poor MAC, but this message only returns the status        //(what is MACed here) and the MAC itself. A real application should return a        //little more information.        offset = Util.setShort(MAC_buffer, START, SW_SUCCESS);        deskey.setKey(keyData, (short)0);        sig.init(deskey, Signature.MODE_SIGN);        short sigLength = sig.sign(MAC_buffer, (short)0, (short)2,             byteArray8, (short)0);                //send R-APDU        //offset = Util.arrayCopyNonAtomic(byteArray8, START, buffer, offset, SIGNATURE_LENGTH);        Util.arrayCopyNonAtomic(byteArray8, START, buffer, START, SIGNATURE_LENGTH);        apdu.setOutgoingAndSend(START, SIGNATURE_LENGTH);                transientBools[UPDATE_INITIALIZED] = false;        }        /**     * Handles Verify Pin APDU.     * @param apdu APDU object     */    private void processVerifyPIN(APDU apdu) {        byte[] buffer = apdu.getBuffer();        byte pinLength = buffer[ISO7816.OFFSET_LC];        byte triesRemaining	= (byte)0;        short count = apdu.setIncomingAndReceive();    // get expected data        if (count < pinLength)             ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);        byte pinType = buffer[ISO7816.OFFSET_P2];                switch (pinType) {        case MASTER_PIN:            if (!masterPIN.check(buffer, ISO7816.OFFSET_CDATA, pinLength)) {                triesRemaining = masterPIN.getTriesRemaining();                //The last nibble of return	code is	number of remaining	tries                ISOException.throwIt((short)(SW_PIN_FAILED + triesRemaining));            }            break;        case USER_PIN:            if (!userPIN.check(buffer, ISO7816.OFFSET_CDATA, pinLength)) {                triesRemaining = userPIN.getTriesRemaining();                //The last nibble of return	code is	number of remaining	tries                ISOException.throwIt((short)(SW_PIN_FAILED + triesRemaining));            }            break;        default:             ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);        }    }        /**     * Verifies numerical limitations on Transaction Amount.     *     * <p><em>NOTE:</em> With some values of maxBalance and maxAmount the logic     * in this method might become somewhat unrealistic. It's the result of using     * short arithmetic on values which might be too big to fit in short variables.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -