eytech/21637/upload/20073174985.doc
IC卡应用目前已深入到银行、电信、社保、智能交能、工商税务、公共事业、加油、烟草等多个应用领域。随着IC应用的进一步推广,一些问题也暴露了出来,以下根据笔者所了解和参与的四川省范围内的一些IC卡应用所出现的一系列情况,浅析其原因及解决办法。
一、 卡片数据安全性差
在IC卡应用中,以逻辑加密卡为主,其代表型号为:4442、4428和1604。其安全特性主要包括:
Ø 通过卡片密码控制IC卡数据的改写;
Ø 通过卡片密码错误计数器控制卡片密码尝试次数;
Ø 通过数据写保护固化一些标识信息;
以下也就是通常所说的逻辑加密的三级加密机制。
但在一些IC卡应用中,IC卡的安全性很差,举例说明:
n 四川省烟草卡(安全度:极差)
该卡采用美国ISSI公司生产的ISSI1604芯片。2K字节的数据区,分为4个物理分区,每个分区都有相应的卡片数据写操作控制密码和数据擦除控制密码,同时卡片还有一总区密码,控制各个分区的操作控制模式。
与逻辑加密卡中其它一些芯片相比,其安全特性应该是更高的,但在烟草卡应用中,卡片密码(包括总密码和各分区写操作密码、擦除密码)都是芯片出厂时的初始值。同时,卡片上所有的数据信息,都采用明文保存,这对IC卡数据的安全性更为不利。
更多的应用都将卡片密码作为卡片数据安全的唯一控制手段。诚然,IC卡的卡片密码控制了IC卡中数据的改写操作,一定程度上可以防止卡片修改和卡片复复制。但仅此显然是一够的。如SLE4428卡,其卡片密码长度为2个字节,取值范围为:65536,而卡片密码可尝试次数为8次,为了保证卡片不损坏,按每张卡尝试7次,则只需要:65536/7=9362张卡即可破取卡片密码。卡片密码的下列安全隐患更具有危险性。
1. 代码遗失:
许多IC卡应用开发商在编写IC卡操作模块时,都将卡片密码串(4-6位BCD码串)以明文的形式放在程序的变量声明中的。如果这部分代码遗失,将导致卡片密码的丢失
2. 程序反汇编:
相应的,如果能将开发商编写的IC卡操作模块反汇编,再由专业的IC卡应用开发人员进行分析,是很可能破获卡片密码串的。
3. 人员隐患:
由于卡片密码串就写在程序代码中,那莫相关的开发人员、系统分析员都是卡片密码泄露的人员隐患。
4. 串行跟踪:
由于卡片密码串与IC卡之间将是串行通信的,即密码串将以按位串行通信的模式被送入IC卡中,所以,通过专门的通信信号分析仪器,参照IC卡操作波形图,即可分析得到IC卡的密码。
5. IC卡应用跟踪:
IC卡的原理是当IC卡的密码验证通过之后,其密码串是可能读出的。如果能跟踪IC卡的具体应用,在IC卡密码验证通过后,非法中断程序,则可读取IC卡的密码串。
二、 数据写入准确性差
与卡片安全性相比,数据写入准确性差更具有代表性和普通性。由于操作IC卡(写/读)类似于标准C51语言下操作内存变量,需要准确的定位数据的每一个字节甚至于是每一位。但在一些IC卡应用中,IC卡中的数据被改写后,即可能发现卡片数据信息出现错误,举例说明:
n 四川省烟草卡(准确性:差)
由于烟草卡中将保存持卡人(烟草经销商)近段时间内的订烟记录(即从烟草公司购买的烟品记录及数量),由于数据信息量大,IC使用一段时间后,即出现卡片上的数据结构出错,导致卡片一些标识信息出错,如持卡人姓名:“李直伟”,但读出的结果为:“李直伟ÿÿ”。
其出差的原因可以参见下图:
错误程序: char name[11]; name[0]=0xc0; name[1]=0xee; name[2]=0xd6; name[3]=0xb1; name[4]=0xce; name[5]=0xb0; name[6]=’\0’; 正确的程序: char name[11]; name[0]=0xc0; name[1]=0xee; name[2]=0xd6; name[3]=0xb1; name[4]=0xce; name[5]=0xb0; name[6]=0xff; name[7]=0xff; name[8]=0xff; name[9]=0xff; name[10]=’\0’;
另外,由于高级语言中,如PB、VB,IC卡的读写机具所提供的操作接口函数在多以字符串(string)进行读写,如果控制不当,则更容易出错。
n 四川省雅安社保卡(原来的系统,现正重新开发设计)
社保(医保)卡在全国正得到大力的推广应用。由于社保卡中存有参保人的个人医保帐户,并可到药店和定点医院进行脱机消费。但在交易过程中,却出现了卡片信息严重错误,特别是个人医保帐户余额由原来的几十元变成了几千上万,最后导致这张卡无法使用(这在全国其它地区同样存在)。
其出错的原因同样是因为写卡过程的不严谨,下面用VB编写其写卡的过程:
Dim sCounter As Single '个人帐户金额 Dim strData As String '写入的字符串 Dim UserInfo as User 结构体,表示持卡人的基本信息 ReadCardInfo sCounter, UserInfo '假设sCounter得到的值为:1999 sCounter = sCounter - 1990 'sCounter=9 strData = Trim(str(sCounter)) 'strData="9" WriteCard strData,4 '改写卡,4个字节 ReadCardInfo sCounter, UserInfo 很显然,sCounter的值即为:9999
操作IC卡一般不建议直接声明字符串变量,而应声明与C语言下的char类型相对应的变量,如在VB下,读写卡时应声明 byte型数组,这样,可以针对每个字节直接进行赋值,同样是完成上图的功能,正确的程序代码应是:
Dim sCounter As Single '个人帐户金额 Dim strData As String '写入的字符串 Dim bData(255) As Byte '写卡缓冲区 Dim bTmp() As Byte '临时缓冲区 Dim UserInfo As User '结构体,表示持卡人的基本信息 Dim I As Integer '循环变量 ReadCardInfo sCounter, UserInfo '假设sCounter得到的值为:199 sCounter = sCounter - 190 'sCounter=9 strData = Trim(str(sCounter)) 'strData="9" bTmp = StrConv(strData, vbFromUnicode) For I = 0 To 3 If I <= UBound(bTmp) Then bData(I) = bTmp Else bData(I) = &HFF '后面填上十六进制的FF表示空 End If Next WriteCard bData,4 '改写卡(4个字节) ReadCardInfo sCounter, UserInfo 很显然,sCounter的值即为:9
由于脱机使用时是“以卡为准”,即只要卡上有钱,就可以消费。如果卡上余额出错,则数据库清算时,就会出现卡片金额与数据库的个人帐户余额不相符。在许多应用中,开发商当发现两者不相符时,会直接将数据库中的个人帐户余额更新卡的余额。这实际上是一对的,至少存在许多不承之处:
1) 数据库中的帐户余额就一定是正确的吗?
由于数据库中的帐户余额是通过帐户初始值减去每一笔消费记录中的消费金额计算而得的,如果在终端交易时发生了写卡出错,就一定能保证写在终端上的消费记录是对的吗?另外,由于终端交易记录要上传到中心服务器,才能完成清算,如何确保所有的交易记录都上传了呢?
2)
| 评论共有1页,当前是第1页 |
首先说明,很多IC卡应用中,都是有用的相同一个密码,长度一般为2-3个字节,其安全隐患在于如果有人破得了一张IC 卡的密码,则整个系统将面临危险。 |
| 评论人:吴润泽 于2007-4-15 13:25:44发表 |
| 评论人:吴润泽 于2007-4-10 11:13:11发表 |