当前位置: 首页 > 面试题库 >

使用Java Card电子钱包

查飞星
2023-03-14
问题内容

我是Java卡初学者,以下示例复制了代码。不知何故,我已经能够部分代码的工作原理。但是仍然对以下内容感到困惑。

.ownerpin的工作方式以及设置销钉的方式和时间。如何进行贷方和借方工作

我了解平衡的工作原理,这方面还不错。下面是代码

wallet.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package classicapplet1;

import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.OwnerPIN;

public class Wallet extends Applet {

    /* constants declaration */
    // code of CLA byte in the command APDU header
    final static byte Wallet_CLA = (byte) 0x80;
    // codes of INS byte in the command APDU header
    final static byte VERIFY = (byte) 0x20;
    final static byte CREDIT = (byte) 0x30;
    final static byte DEBIT = (byte) 0x40;
    final static byte GET_BALANCE = (byte) 0x50;
    // maximum balance
    final static short MAX_BALANCE = 0x7FFF;
    // maximum transaction amount
    final static byte MAX_TRANSACTION_AMOUNT = 127;
    // maximum number of incorrect tries before the
    // PIN is blocked
    final static byte PIN_TRY_LIMIT = (byte) 0x03;
    // maximum size PIN
    final static byte MAX_PIN_SIZE = (byte) 0x08;
    // signal that the PIN verification failed
    final static short SW_VERIFICATION_FAILED = 0x6300;
    // signal the the PIN validation is required
    // for a credit or a debit transaction
    final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301;
    // signal invalid transaction amount
    // amount > MAX_TRANSACTION_AMOUNT or amount < 0
    final static short SW_INVALID_TRANSACTION_AMOUNT = 0x6A83;
    // signal that the balance exceed the maximum
    final static short SW_EXCEED_MAXIMUM_BALANCE = 0x6A84;
    // signal the the balance becomes negative
    final static short SW_NEGATIVE_BALANCE = 0x6A85;

    /* instance variables declaration */
    OwnerPIN pin;
    short balance;

    private Wallet(byte[] bArray, short bOffset, byte bLength) {

        // It is good programming practice to allocate
        // all the memory that an applet needs during
        // its lifetime inside the constructor
        pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);

        byte iLen = bArray[bOffset]; // aid length
        bOffset = (short) (bOffset + iLen + 1);
        byte cLen = bArray[bOffset]; // info length
        bOffset = (short) (bOffset + cLen + 1);
        byte aLen = bArray[bOffset]; // applet data length

        // The installation parameters contain the PIN
        // initialization value
        pin.update(bArray, (short) (bOffset + 1), aLen);
        register();

    } // end of the constructor

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        // create a Wallet applet instance
        new Wallet(bArray, bOffset, bLength);
    } // end of install method

    public boolean select() {

        // The applet declines to be selected
        // if the pin is blocked.
        if (pin.getTriesRemaining() == 0) {
            return false;
        }

        return true;

    }// end of select method

    public void deselect() {

        // reset the pin value
        pin.reset();

    }

    public void process(APDU apdu) {

        // APDU object carries a byte array (buffer) to
        // transfer incoming and outgoing APDU header
        // and data bytes between card and CAD

        // At this point, only the first header bytes
        // [CLA, INS, P1, P2, P3] are available in
        // the APDU buffer.
        // The interface javacard.framework.ISO7816
        // declares constants to denote the offset of
        // these bytes in the APDU buffer

        byte[] buffer = apdu.getBuffer();
        // check SELECT APDU command

        if (apdu.isISOInterindustryCLA()) {
            if (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4)) {
                return;
            }
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
        }

        // verify the reset of commands have the
        // correct CLA byte, which specifies the
        // command structure
        if (buffer[ISO7816.OFFSET_CLA] != Wallet_CLA) {
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
        }

        switch (buffer[ISO7816.OFFSET_INS]) {
            case GET_BALANCE:
                getBalance(apdu);
                return;
            case DEBIT:
                debit(apdu);
                return;
            case CREDIT:
                credit(apdu);
                return;
            case VERIFY:
                verify(apdu);
                return;
            default:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }

    } // end of process method

    private void credit(APDU apdu) {

        // access authentication
        if (!pin.isValidated()) {
            ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
        }

        byte[] buffer = apdu.getBuffer();

        // Lc byte denotes the number of bytes in the
        // data field of the command APDU
        byte numBytes = buffer[ISO7816.OFFSET_LC];

        // indicate that this APDU has incoming data
        // and receive data starting from the offset
        // ISO7816.OFFSET_CDATA following the 5 header
        // bytes.
        byte byteRead = (byte) (apdu.setIncomingAndReceive());

        // it is an error if the number of data bytes
        // read does not match the number in Lc byte
        if ((numBytes != 1) || (byteRead != 1)) {
            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        }

        // get the credit amount
        byte creditAmount = buffer[ISO7816.OFFSET_CDATA];

        // check the credit amount
        if ((creditAmount > MAX_TRANSACTION_AMOUNT) || (creditAmount < 0)) {
            ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
        }

        // check the new balance
        if ((short) (balance + creditAmount) > MAX_BALANCE) {
            ISOException.throwIt(SW_EXCEED_MAXIMUM_BALANCE);
        }

        // credit the amount
        balance = (short) (balance + creditAmount);

    } // end of deposit method

    private void debit(APDU apdu) {

        // access authentication
        if (!pin.isValidated()) {
            ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
        }

        byte[] buffer = apdu.getBuffer();

        byte numBytes = (buffer[ISO7816.OFFSET_LC]);

        byte byteRead = (byte) (apdu.setIncomingAndReceive());

        if ((numBytes != 1) || (byteRead != 1)) {
            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        }

        // get debit amount
        byte debitAmount = buffer[ISO7816.OFFSET_CDATA];

        // check debit amount
        if ((debitAmount > MAX_TRANSACTION_AMOUNT) || (debitAmount < 0)) {
            ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
        }

        // check the new balance
        if ((short) (balance - debitAmount) < (short) 0) {
            ISOException.throwIt(SW_NEGATIVE_BALANCE);
        }

        balance = (short) (balance - debitAmount);

    } // end of debit method

    private void getBalance(APDU apdu) {

        byte[] buffer = apdu.getBuffer();

        // inform system that the applet has finished
        // processing the command and the system should
        // now prepare to construct a response APDU
        // which contains data field
        short le = apdu.setOutgoing();

        if (le < 2) {
            ISOException.throwIt((byte) 0x6A86);
        }

        // informs the CAD the actual number of bytes
        // returned
        apdu.setOutgoingLength((byte) 2);

        // move the balance data into the APDU buffer
        // starting at the offset 0
        buffer[0] = (byte) (balance >> 8);
        buffer[1] = (byte) (balance & 0xFF);

        // send the 2-byte balance at the offset
        // 0 in the apdu buffer
        apdu.sendBytes((short) 0, (short) 2);

    } // end of getBalance method

    private void verify(APDU apdu) {

        byte[] buffer = apdu.getBuffer();
        // retrieve the PIN data for validation.
        byte byteRead = (byte) (apdu.setIncomingAndReceive());

        // check pin
        // the PIN data is read into the APDU buffer
        // at the offset ISO7816.OFFSET_CDATA
        // the PIN data length = byteRead
        if (pin.check(buffer, ISO7816.OFFSET_CDATA, byteRead) == false) {
            ISOException.throwIt(SW_VERIFICATION_FAILED);
        }

    } // end of validate method
} // end of class Wallet

下面是scr文件wallet.scr

    //Test script for Applet 'Wallet'

powerup;
// Select Wallet //aid/27ADED2B70/39
0x00 0xA4 0x04 0x00 0X06 0X27 0XAD 0XED 0X2B 0X70 0X3A 0x7F;

//Send the APDU here
//0x80 0xCA 0x00 0x00 <length> <data> 0x7F;
0x80 0x50 0x00 0x00 0x00 0x7F;
powerdown;

上面的wallet.scr,我用来检查余额,输出是:

CLA: 80, INS: 50, P1: 00, P2: 00, Lc: 00, Le: 02, 00, 00, SW1: 90, SW2: 00

这是预期的。但是,当我尝试贷记和借记时,该怎么办?提前致谢


问题答案:

调用贷记(或借记)方法,您需要更改 APDU*INS 字节以匹配所需的值。 *

在你的代码已经发布了 INS信用的0x30INS借记0x40的

因此,在发送选择的APDU之后,您需要发送以下内容

信用

0x80 0x30 0x00 0x00 0x01 (1 byte containing the Credit value) 0x00

借方

0x80 0x30 0x00 0x00 0x01 (1 byte containing the Debit value) 0x00

在两种情况下,您都应该收到 0x63 0x61 作为响应,指示您需要执行 验证PIN 命令。

所述 验证PIN 命令应当被构造为:

0x80 0x20 0x00 0x00 (1 byte indicating the number of PIN bytes) (The PIN bytes) 0x00

例如,如果PIN码为 4位数字 并将其设置为值 “ 1234”,则 您将看到以下内容:

0x80 0x20 0x00 0x00 0x02 0x12 0x34 0x00

如果正确 验证 了PIN码,您将得到一个 0x90 0x00 作为响应

如果PIN码 不正确, 您将收到 0x63 0x00 响应

此应用程序的PIN值在小程序的 安装参数中 设置,顾名思义,该 参数 是将小程序安装到卡(或仿真器)上时

希望这可以帮助



 类似资料:
  • 使用电子钱包 若要使用此机能,可能需先更新系统软件。 进入(PlayStation®Store),可使用电子钱包,购买各种需付费商品或服务。每个PlayStation®Network的主账户都准备了一个电子钱包。使用电子钱包前,需先预付电子货币。 预付电子货币 可使用信用卡、PlayStation®Network Card*,替账户预付电子货币。可选择之预付方法、货币和预付上限额等因国家或区域而异

  • 小钱袋子是一款免费网络版记帐系统(B/S),适用于个人记帐、家庭记帐、团队记帐,帮你记录你财富的增长过程。该系统使用简单方便,界面设计美观,用户体验良好,代码安全性高。 系统功能 基本信息管理 用户管理 收入项目管理 支出项目管理 帐目管理 收入记账 支出记账 借贷记账 统计报表 账户总收入统计与收入明细统计 账户总支出统计与支出明细统计 账户总借贷统计与借贷明细统计 账户净余额统计 账户当日明细

  • 问题内容: 在最新版本(v0.31.0)中,电子附带了静态链接的FFMpeg库(不是命令行工具,请参见#2588) 我知道很多用于ffmpeg的nodejs模块,但是它们看起来都像是命令行工具的api,那么理想情况下我该如何访问与电子捆绑在一起的ffmpeg库并编码流? 问题答案: 当前这是不可能的,因为没有针对Node.js的不错的库。意思是,只有这样抽象了CLI。但是,可以将其编译和链接为节点

  • 我有一个使用commons电子邮件的项目(http://search.maven.org/#artifactdetails|组织。阿帕奇。commons | commons电子邮件| 1.2 | jar)通过maven发送。我想使用电子邮件模拟类(http://commons.apache.org/email/testapidocs/org/apache/commons/mail/mocks/Mo

  • 按钮 颜色传感器 蜂鸣器 陀螺仪 冷光线 多路触摸传感器 温湿度传感器 摇杆 旋钮 LED LED 面板 LED 灯带 光线传感器 双路红外开关 电机 显示屏 人体红外传感器 测距传感器 8分显示 舵机 土壤湿度传感器 声音传感器 温度传感器 语音识别