基于Java智能卡的电子钱包应用开发
目 录
第一章Java智能卡的设计概要 1
1.1项目背景与意义 1
1.2 Java智能卡发展现状 1
1.3项目设计内容 2
1.4项目设计的人员分工 7
第二章电子钱包应用的设计过程 7
第三章电子钱包应用的功能测试 7
第四章项目总结与感想 16
智能卡(smartcard)在包括电信、银行、公交、医疗、身份证件、数字电视、安全认证等与普通消费者息息相关的领域均获得了广泛的应用。在未来移动支付、信用卡等更加普及、对个人信息安全有更高诉求的时代,智能卡仍将发挥不可替代的重要作用。
传统的Native卡在互操作性和多功能应用上的不足,在应用开发时的高难度、高成本已经成为限制智能卡进一步发展的最大障碍。在探索如何解决这些矛盾的过程中,以Sun为代表的公司开始尝试将更通用和安全的Java平台引入智能卡行业,Java卡便应运而生。
本项目是基于Java智能卡的应用Applet开发,实现具有电子钱包功能的金融智能卡应用系统。
JAVA智能卡是JAVA语言与智能卡相结合的产物。概括说来,JAVA卡就是能运行JAVA语言的CPU卡。JAVA卡采用的是一种新的智能卡编程系统,它在智能卡上建立JAVA虚拟机及相应的运行环境,JAVA卡程序用标准的JAVA开发工具编写,然后下载到智能卡上由虚拟机解释执行。
现阶段JAVA卡有如下几大优点:
1、跨平台应用
JAVA编译器产生不依赖于平台的字节码,字节码在虚拟机中运行。它的代码独立于平台,可移植性好,可以跨平台运行,达到“编写一次,到处运行”的理想境界。基于JAVA语言开发的智能卡应用程序可以运行在所有的JAVA智能卡上。
2、开发效率高
其它的智能卡应用程序在开发时都以汇编语言外加C语言为主,需要对智能卡硬件有很深的专业知识,编程复杂,开发速度慢,成本高。JAVA语言是面向对象的高级语言,提供大量的通用API和密码算法API,使得编程应用变的简单。
3、安全性好
JAVA卡有用防火墙来隔离Applet之间的非法访问。JAVA语言的“解释性”执行的特点,使得它可以在执行时对代码进行彻底的检查,以防篡改、病毒和其它威胁,其安全程度远远超过了传统的预编译代码。
4、标准兼容
JAVA卡技术以ISO-7816标准为基础,因此可以兼容按ISO-7816开发的所有智能卡系统和应用系统。Applet不仅能在JAVA智能卡上相互执行,而且也能被现有的IC卡或智能卡读写设备所接受,因此JAVA智能卡具有很好的标准兼容性。
5、可扩展性好
非JAVA智能卡新增业务的时候,需要根据业务需求修改底层的用汇编编写的卡操作系统(COS);对于JAVA智能卡,开发人员不需要了解底层的硬件结构和相关指令集,只需要调用卡上提供的一套通用的API就可以增加新业务而不必修改底层系统。
(1)建立文件系统和写入文件及读取文件
电子钱包设计首先要在空白卡片上建立文件系统,包括四大类文件,应用基本文件——也就是发卡方官方的一些信息,然后是持卡人个人信息的文件,再就是EP(电子钱包)文件,以及最重要的密钥文件。并且密钥文件必须先于其他三个文件之前创建,因为没密码你弄啥操作不科学呀。
几大文件反应到代码中就是几大数据结构:
然后就是创建文件和将密钥等信息写入文件
既然是要创建文件,当然就要先从终端获取apdu命令,判断它的命令里面是不是要卡片创建文件,怎么判断呢?通过ins值,就是这句代码:
condef.java文件里面定义了一些ins值常量,还有就是如果是要创建文件,那要创建的是什么文件呢,通过pdata的第一位判断,也就是pdata[0]。既然已经判断出了apdu命令是要我们创建文件,同时又判断出了要创建的是什么文件,接下来就是直接调用几大文件数据结构的接口去创建相应的文件,同时,这里要判断一些异常的情况,也就是apdu命令有输入错误的情况,然后返回相应的异常给终端。比如:
然后就是向文件中写入密钥和持卡人信息等信息。
首先是写入密钥write_key,密钥分为三种:TAC密钥、圈存密钥、消费密钥:
直接调用keyfile数据结构里面的addkey函数进行密钥增加:
使用addkey函数需要传递三个参数进去,第一个是标签,也就是密钥的类型(刚才说的三种:圈存、消费、TAC),第二个是密钥的长度,第三个是密钥的值,tag参数对应的是apdu命令的p2参数,密钥长度对应的而是apdu的lc,值对应data。然后就是write_binary,写二进制文件(应用基本信息和持卡人基本信息),类似的,调用BinaryFile数据结构里面的write_bineary函数。
最后是读取二进制文件信息read_binary,理解了上面这里就很简单了,没什么好说的,直接调用BinaryFile结构体里面的read_binary函数:
(2)圈存
圈存流程图:
首先是终端给卡片发送圈存命令:
卡片收到这个初始化命令之后,首先是根据密钥标识符找出相应的圈存密钥,并做一系列的判断(比如没找到或者啥的),反映到代码就是根据判断抛出异常,然后如果找到了密钥而且没什么问题的话,就继续往下处理,首先生成一个随机数,然后用刚才查找到的圈存密钥生成一个过程密钥(为什么不直接用圈存密钥而要弄个新的过程密钥?因为直接用圈存密钥容易被破解啊,网络安全方面的知识,同个密钥一直重复用就更容易被破解,所以要把它结合一个随机数产生一个每次都变化的过程密钥)。过程密钥的生成方式:其输入的数据为伪随机数||电子钱包联机交易序号||8000,密钥为所查找到的圈存密钥。(||这个符号表示的是字符串连接而不是代码中的或)。然后IC卡利用所生成的过程密钥产生MAC1。其输入的数据为电子钱包余额(交易前)||交易金额||交易类型标识(圈存是02)||终端机编号,密钥为过程密钥。在进行这些操作后,IC卡将返回相应的数据给终端:
继而终端将命令传送给主机,主机程序验证mac1,如果验证通过,则同意交易进行,主机从持卡人账户扣除相应的金额。接下来终端再给卡片发送圈存命令。
然后就是:
1、I C卡收到圈存命令后,利用过程密钥生成MAC2。其输入数据为交易金额||交易类型标识(圈存的都是02)||终端机编号||交易日期(主机)||交易时间(主机)。密钥为过程密钥。与圈存命令传送的MAC2进行比较,如果相同,则MAC2有效
2、 IC卡将电子钱包联机交易序号加1,并且把交易金额加在电子钱包的余额上。
3、 IC卡生成TAC码。TAC码的生成方式和MAC码的生成方式一致。其输入的数据:电子钱包余额(交易后)||电子钱包联机交易序号(加1前)||交易金额||交易类型标识(圈存是02)||终端机编号||交易日期(主机)||交易时间(主机)。密钥为TAC密码最左8个字节与TAC密码最右8个字节异或的结果。
IC卡将TAC码返回给终端。至此,IC卡端的圈存交易已经完成了。
这里牵涉到两个重要的辅助函数,一个是用来生成过程密钥的3DES加密函数,流程如下:
另一个是用来生成MAC和TAC的gmac4函数,进行多轮DES加密,流程图如下:
根据相应的流程图可以实现相应的加密函数。
(3)消费
流程图如下:
会发现与圈存的流程大致差不多,只不过有一个很大的差别就是mac值的生成,与圈存不同的是,消费流程中终端首先给卡片发送消费初始化命令,卡片收到命令之后并不会产生mac1的值,而只是产生一个伪随机数返回给终端,然后终端收到返回数据之后,再用这个伪随机数去产生过程密钥,进而产生mac1值,然后将这个mac1的值附带在消费命令中发给卡片,卡片收到之后,验证mac1并产生mac2和TAC的值返回给终端。
最后还有个余额查询的实现,这个比较简单,终端给卡片发送余额查询命令后,卡片调用相应的余额查询函数并返回余额给终端。
吕浪负责关键模块代码的编写及最终的验收,张志威负责部分代码的编写及对现有代码的改善以及实验报告部分内容。
详细描述设计过程,描述清楚各个部分之间的联系,可以截部分重要代码。
(1)首先是输入建立文件和导入密钥等等的命令,这里可以直接把命令写在一个脚本里,然后直接执行这个脚本即可:
执行脚本:
脚本内容:
(2)圈存
执行完脚本的最后一句会得到卡片执行初始化圈存命令返回的数据,其中最后8葛byte是伪随机数和mac1的值,取其中的伪随机数出来:
用这个伪随机数拼接其他相应的数据,密钥为相应的圈存密钥,在DES.exe中手动产生一个过程密钥:
然后再用这个过程密钥去生成mac1,取mac1的值前四个字节与卡片返回的mac1进行比较,相同验证成功:
继续用这个过程密钥去生成mac2的值,输入数据要改成相应的数据拼接:
取mac2前四个字节出来放到圈存的命令当中发送给卡片:
卡片执行圈存命令验证通过mac2的值之后会返回TAC码,接下来用DES.exe工具手动生成TAC,与卡片返回的TAC进行比对,相同验证成功:
(3)消费
至此圈存过程的仿真结束并且全部验证通过,接下来测试消费过程。首先终端给卡片发送消费初始化命令:
卡片返回伪随机数,取出这4bytes的伪随机数,生成一个过程密钥:
再用这个过程密钥生成一个mac1的值:
然后取mac1值得前四个bytes放到圈存的命令当中发送给卡片:
卡片验证通过mac1然后给终端发挥mac2和TAC数据,接下来继续用DES.exe工具手动生成mac2来检验卡片返回的数据,验证通过:
然后继续生成TAC,同样验证通过:
此时卡片应该是余额为0的,所以继续发送消费初始化命令给卡片会返回余额不足的异常代号:
最后是查询余额功能的测试:
由于前面圈存和余额的金额都一样,所以金额回归为0,卡片返回的余额显示为0
这是圈存和消费(初始化和消费)以及查询余额的命令格式:
由于手动用DES.exe工具牵涉到的数据较多,我把一些相关的数据都提前准备在文件里,用到工具的时候就可以直接复制粘贴了:
至此,功能测试全部完成并且全部通过,在最后的验收接上读卡器和卡片中,全部功能也验证通过,并且鲁棒性较强。