java card平台详解

原文地址:http://blog.csdn.net/javacardsolutions/article/details/6658989

1、Native cos的基本架构

首先我们来回顾一下以往native cos的基本架构

HAL层、通讯层、文件系统、算法、安全模块、个人化命令、应用命令等。

一般一个native cos只实现一个应用规范,也有同时实现两个或者更多应用规范的COS,COS实现规范里面定义的所有应用命令。

卡片上电之后,收到卡机发来的APDU后,通过解析APDU头的INS(还需要检查CLA、P1、P2之类)等步骤来找到该命令所对应的函数执行并返回结果。可以简单点来说就是一个APDU指令对应于卡内的一个功能函数,对于非规范内规定的INS,卡片一般都直接返回6d00表示不支持或者无法解析的指令。


2、java卡特点的简单介绍

Java卡是个多应用智能卡平台,与native cos有本质的区别 ,它不是实现某个应用规范或者多个应用规范的cos,而是为cos应用开发人员提供了另外一种途径来实现应用规范。简单的类比一下,java卡和native卡的区别就相当于PC上用C语言开发应用程序和用java语言开发应用程序的区别。

java卡是个平台,是个应用容器,可以动态的装载不同的应用,也可以装载很多相同应用的不同实例。java卡把native卡里面的HAL层、通讯层、文件系统、算法、安全等都封装成了API库,所以java卡上的智能卡应用开发人员和传统的native卡的开发人员相比,工作难度要降低了很多,像文件系统、掉电保护等等通通不用再设计了。

所以java卡和传统native卡在架构上自然有很大的区别。



3、代码实例

章主要从代码级的角度来看Java卡的执行流程。

########################################################################################################

先看一个简单的java卡的applet代码(HelloWord):

从下面的代码可以看出一个java卡应用的简单构成,install函数和process函数。其它可选接口如select、deselect和uninstall函数这里没有。

install函数负责安装这个应用,进行一些对象的初始化和注册,告诉jcre这个应用已经被成功安装,接下来就可以对这个应用进行选择和其它命令执行。

process函数是应用的最重要的命令处理函数,这里解析apdu的ins,进行命令分派,相当于native cos的commandDispatcher函数。当然这个示例比较简单,仅仅是返回一个helloword字符串。

package com.sun.javacard.samples.HelloWorld;

import javacard.framework.*;

public class HelloWorld extends Applet
{
    private byte[] echoBytes;
    private static final short LENGTH_ECHO_BYTES = 256;
    //private test testobj;

    /**
     * Only this class's install method should create the applet object.
     */
    protected HelloWorld()
    {
     //testobj = new test();
        
        //testobj.setsvalue((short)10);
        //testobj.setivalue((int)20);
        echoBytes = new byte[LENGTH_ECHO_BYTES];
        register();
    }

    /**
     * Installs this applet.
     * @param bArray the array containing installation parameters
     * @param bOffset the starting offset in bArray
     * @param bLength the length in bytes of the parameter data in bArray
     */
    public static void install(byte[] bArray, short bOffset, byte bLength)
    {
        new HelloWorld();
    }

    /**
     * Processes an incoming APDU.
     * @see APDU
     * @param apdu the incoming APDU
     * @exception ISOException with the response bytes per ISO 7816-4
     */
    public void process(APDU apdu)
    {
        byte buffer[] = apdu.getBuffer();

  short bytesRead = apdu.setIncomingAndReceive();
  short echoOffset = (short)0;

  while ( bytesRead > 0 ) {
            Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead);
            echoOffset += bytesRead;
            bytesRead = apdu.receiveBytes(ISO7816.OFFSET_CDATA);
        }

        apdu.setOutgoing();
        apdu.setOutgoingLength( (short) (echoOffset + 5) );

        // echo header
        apdu.sendBytes( (short)0, (short) 5);
        // echo data
        apdu.sendBytesLong( echoBytes, (short) 0, echoOffset );
    }

}

########################################################################################################

上面我们简单看了一下一个java卡应用的简单示例,下面我们将看一下java卡运行时的主函数。

下面这个函数就是java卡的入口main函数,在javacard\framework\Dispatcher.java文件中。

芯片在做了一些初始化之后,加载这个main函数,交给java虚拟机进行执行,进入java卡执行流程。

static void main()
 {
  if (!NativeMethods.isCardInitialized())
   cardInit();

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~判断卡片是否已经“个人化”了,这里的nativemethods是调用的c接口,库进行了一层封装,提供java代码调用c代码的一个机制。

  cardReset();

~~~~~~~~~~卡片重新复位


  short sw = 0;
  do
  {
   do
   {
    PrivAccess.resetSelectingAppletFlag();
    PrivAccess.resetProcessMethodFlag();


    theAPDU.complete(sw);

~~~~~~~~~~~~~~~这是APDU接口,负责接收APDU和发送返回值和错误码,如果卡机没有下发apdu,则卡片在这里一直等待接收。对应于native cos的receiveApduHeader


    byte activeInterface = NativeMethods.getActiveInterface();
    try
    {
     theAPDU.verifyLe();
     if (processAndForward())

~~~~~~~~~~~~~~~~~~~~~~该函数进行一些预处理,如果是打开通道命令,则打开相应通道回到接收apdu位置等待接收下一条命令。如果是其它命令,则继续往下执行
     {
      byte commandChannel = NativeMethods.getCurrentlySelectedChannel();
      if (PrivAccess.getSelectedAppID(commandChannel, activeInterface) == -1)
       ISOException.throwIt((short)27033);
      PrivAccess.setProcessMethodFlag();
      Applet selectedApplet = PrivAccess.getSelectedApplet(commandChannel, activeInterface);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~此函数是获取当前被选择的应用
      if (selectedApplet instanceof ExtendedLength)
       theAPDU.markExtendedSupport(true);
      else
       theAPDU.markExtendedSupport(false);
      selectedApplet.process(theAPDU);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~调用被选择应用的process函数,进行命令处理。相当于native cos的命令分派和处理函数
      if (JCSystem.getTransactionDepth() != 0)
       TransactionException.throwIt((short)1);
     }
     sw = -28672;
    }
    catch (ISOException ex)
    {
     sw = ex.getReason();
    }
    catch (Throwable e)
    {
     sw = 28416;
    }
    if (JCSystem.getTransactionDepth() != 0)
     JCSystem.abortTransaction();
   } while (!thePrivAccess.isGarbageCollectionRequested());
   GarbageCollector.startGC();

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~这里执行垃圾回收,如果前面执行的代码有设置请求垃圾回收位。
  } while (true);
 }

 

 private static boolean processAndForward()
  throws ISOException
 {
  if (theAPDU.isISOInterindustryCLA())
  {
   setAPDUChannel();
   switch (theAPDUBuffer[1])
   {
   default:
    break;

   case -92: 
    if (!theAPDU.isSecureMessagingCLA())
    {
     theDispatcher.selectAPDU(theAPDU);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~选择应用命令,根据aid找到应用,然后执行该应用的select接口。
     return true;
    }
    break;

   case 112: // 'p'
    if (theAPDU.isSecureMessagingCLA())
     ISOException.throwIt((short)26754);
    theDispatcher.manageChannelAPDU(theAPDU);
    return false;
   }
  }
  setAPDUChannel();
  return true;
 }

 

########################################################################################################

从上面可以看出一个java卡应用是如何被成功调用的,可以从中看出java卡和native卡的区别。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值