打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
2021最新整理Java教程:Java 智能卡迷你计算器

介绍

    本文是关于编写基于Java智能卡的应用程序。本教程将帮助初学者理解Java智能卡和主机应用程序之间的概念和通信。我已经看到Java智能卡技术的初学者提出了一些简单的问题,所以我决定为他们提供一个完整的例子来帮助他们入门。

    在这篇文章/教程中,我将解释一个示例应用程序,一个计算器,它将执行四个基本的计算操作,即,,+,-,*和/。

    背景

    为了理解本教程,你必须知道J2SE,并且应该对(Java)智能卡有基本的了解。要了解什么是Java卡,请访问Oracle官方网站。此外,您可能需要对以下标准有基本的了解。

    -ISO7816-3

    -ISO7816-4

    -全球平台2.1/2.2

    假设

    我假设你有智能卡和智能卡阅读器,并且你能够加载和安装本教程/文章提供的.cap文件。工具使用

    -网豆。

    -Java智能卡

    -戴尔键盘阅读器

    定义

    什么是智能卡小程序?

    驻留在智能卡上的应用程序叫做SmartCardApplet,它是写在电脑上,然后安装在智能卡上。它是在电脑上编写,然后安装在智能卡上。

    什么是主机应用?

    它是驻留在计算机上或通过APDU与智能卡交互的应用程序。这个应用程序可以用任何编程语言编写。

    什么是APDU?

    APDU是ApplicationProgrammingDataUnit的缩写,是小程序与主机应用程序之间的通信媒介。它是applet和主机应用程序之间的通信媒介。所有的通信都是通过APDUs在主机应用程序和applet之间完成的。

    APDU有两种类型,一种是命令APDU,由主机应用程序向小程序发送,第二种是响应APDU,作为命令APDU的响应发送回主机应用程序。

    什么是APDU结构?

    一个APDU由以下字段组成。

    -CLA:是APDU的类别。

    -INS:指示主机应用程序要做什么

    -P1和P2:切换参数

    -LC:数据的长度

    -数据。实际数据被发送到卡上

    -LE:从卡上得到的数据长度

    上述字段的顺序应该是。

    CLAINSP1P2LCDataLE。

    使用代码

    Java卡应用程序是一种ClientServer应用程序,其中智能卡始终保持空闲状态,并对主机应用程序向其发出的命令作出响应。主机应用程序向它发送的命令。总是有一个响应APDU的命令APDU。

    在任何智能卡应用程序中,我们需要检测与计算机相连的读卡器,然后必须与该读卡器建立连接,并与读卡器内的卡连接。

    在计算器应用中,我使用了一个组合框来显示所有可用的读卡器和一个名为"刷新"的按钮,当点击该按钮时,组合框中的终端/读卡器就会弹出。然后,你必须选择一个终端,并点击'连接'按钮来与智能卡连接。

    我使用的是JDK1.6以上版本的SmartCardIOAPI,这意味着你不需要下载它,只要导入它就可以使用。在计算器应用中,使用了以下SmartCardIO类。

import javax.smartcardio.Card;import javax.smartcardio.CardChannel;import javax.smartcardio.CardException;import javax.smartcardio.CardTerminal;import javax.smartcardio.CommandAPDU;import javax.smartcardio.ResponseAPDU;import javax.smartcardio.TerminalFactory;

    为了开始与卡的通信,我们需要先得到读卡器/终端。为此,Java提供了一个类TerminalFactory,这个类用来获取所有与计算机相连的终端。

public List<CardTerminal> getTerminals() throws Exception{
    factory = TerminalFactory.getDefault();
    terminals = factory.terminals().list();    return terminals;
}

    以上函数返回一个列表,我们可以在组合框中显示。

    从组合框中选择一个终端后,用户必须点击连接按钮。如果有一个卡存在,并且它的ATR工作正常,那么在框架的右下方将显示一个文本Connected,否则将显示相应的错误信息。

    为了与智能卡连接,我们使用CardTerminal类的Connect()函数。要通过T=0进行连接,你需要使用Connect("T=0"),而对于T=1,你必须使用Connect("T=1")。但是如果你不确定,你可以使用*,SmartCardIO会自动检测通信协议。

    以下是执行连接操作的方法。

protected void connectToCard(CardTerminal terninalSource) throws CardException {
    terminal = terninalSource;
    card = terminal.connect("*");
}

    与卡连接成功后,你需要在输入文件中输入数字,然后按计算操作按钮。

    在这里我将解释(+)的操作,其余都是一样的。

private void add_buttonActionPerformed(java.awt.event.ActionEvent evt) {                                           
        
    String command = "00A404000E63616C63756C61746F722E61707000";    byte[] apdu = JavaSmartcard.hexStringToByteArray(command);    if (!selectApplet(apdu))
    {        return;
    }    
    byte[] data_LC;    try 
    {
        data_LC = getLCData(this.digit1_TextField.getText(), this.digit2_TextField.getText());
    }    catch (Exception ex) 
    {
       JOptionPane.showMessageDialog(this, "Only digits are allowed to input in the fields\n"+
         ex.getMessage(), "Type Error", JOptionPane.ERROR_MESSAGE);       return;
    }
    
    command = "A000000002"; 
    
    String LC_Hex = JavaSmartcard.byteArrayToHexString(data_LC);     
         
    command = command.concat(LC_Hex);                
    
    apdu = JavaSmartcard.hexStringToByteArray(command);
    System.out.println(""+ JavaSmartcard.htos(apdu));    try
    {
        javaCard.sendApdu(apdu);        byte[] data = javaCard.getData();        
        this.status_Label.setText(""+Integer.toHexString(javaCard.getStatusWords()).toUpperCase());        this.result_Label.setText(new BigInteger(data)+"");
    } 
    catch (CardException | IllegalArgumentException ex) 
    {
        JOptionPane.showMessageDialog(this, "Error while tried to send command APDU\n"+
          ex.getMessage()+"", "APDU sending fail", JOptionPane.ERROR_MESSAGE);
    }
}

    在上面的功能中,我首先选择小程序,选择成功后,我准备APDU,它将指示小程序做什么,它有什么数据。

command = "00A404000E63616C63756C61746F722E61707000";

    上面是选择小程序的APDU,因为我们需要先选择我们的计算器小程序来进行计算,否则默认的小程序可能不接受你后续的命令APDU。

byte[] apdu = JavaSmartcard.hexStringToByteArray(command);

    在准备好APDU后,我要把它转换成字节数组来传输到卡上,hexStringToByteArray是一个实用的函数,用来把一个十六进制字符串转换成字节数组。

command = "A000000002";

    上面的APDUA000000002是APDU,它将告诉小程序,你必须添加给定的两个数字。我将在下面解释它的字段。

    -CLA:AO

    -INS:00

    -P1和P2:00,00

    -LC:02

    数据部分的计算方法如下。

private byte[] getLCData(String byte1Str, String byte2Str) throws Exception
{    byte[] data_LC = new byte[2];    byte byte1 =  Byte.parseByte(byte1Str );    byte byte2 =  Byte.parseByte(byte2Str);
    data_LC[0] = byte1;
    data_LC[1] = byte2;  
    return data_LC;
}

    我正在将两个TextFields的输入转换为字节,然后将这些字节复制到一个字节数组中传送到卡上。

    最终的APDU将如下所示。让用户输入5和5并输入。

A0 00 00 00 02 05 05

    当智能卡收到APDU时,它将对其进行解释,并找到INS字段,以了解Host应用程序想要做什么,然后它将从数据部分获取数据(数字),并将其添加并以响应APDU的形式返回给Host应用程序。

    当收到响应APDU时,我们可以确定STATUSWORD来了解计算过程中发生了什么。如果卡返回的STATUSWORD为0x9000,则表示一切正常,否则可能会出现错误,或者执行进一步的操作以获得实际的响应APDU。

public int getStatusWords() {    return rAPDU.getSW();
}

    上面的函数是用来获取卡片返回的STATUSWROD,通过使用下面的函数,我得到的是Data部分。

public byte[] getData() {    if (rAPDU!=null) {        return rAPDU.getData();
    }    else {        return null;
    }
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Java Card应用程序体系结构概述
JAVA串口编程
【学术论文】Java卡虚拟机的安全攻击技术及防御技术研究
java-使用PC / SC阅读器验证Ultralight EV1
主题:java 加密解密简单实现
JAVA上DES加密算法的实现用例
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服