惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
博客园_首页
H
Help Net Security
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
B
Blog
I
InfoQ
SecWiki News
SecWiki News
T
Tailwind CSS Blog
Spread Privacy
Spread Privacy
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
N
Netflix TechBlog - Medium
P
Palo Alto Networks Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Vercel News
Vercel News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
Kaspersky official blog
M
MIT News - Artificial intelligence
S
Schneier on Security
T
Threat Research - Cisco Blogs
F
Fortinet All Blogs
Cyberwarzone
Cyberwarzone
Scott Helme
Scott Helme
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
MyScale Blog
MyScale Blog
The Cloudflare Blog
Recent Announcements
Recent Announcements
Security Latest
Security Latest
G
GRAHAM CLULEY
IT之家
IT之家
Y
Y Combinator Blog
The Last Watchdog
The Last Watchdog
腾讯CDC
Google DeepMind News
Google DeepMind News
V
V2EX
S
Securelist
TaoSecurity Blog
TaoSecurity Blog
B
Blog RSS Feed
S
SegmentFault 最新的问题
博客园 - 叶小钗
P
Proofpoint News Feed
云风的 BLOG
云风的 BLOG
Project Zero
Project Zero
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
F
Full Disclosure

博客园 - SCPlatform

windown 使用python 自动切换网络 CPU封装技术介绍 openssl unicode编译以及VC++2015环境下的问题 重新开启此博 MIFARE Classic S50技术详解 Mifare简介 如何获取JavaCard栈信息 JavaCard应用开发环境 如何统合分析一张JavaCard BER-TLV数据结构 智能卡中的数据结构 加密解密算法 SCPlatform博客文章总目录 C#实现简体中文和繁体中文的转换 QueryString 整站过滤 关于脚本注入的问题 开发Blog需注意的Blog基本特征和功能要素 java 学习步骤 CodeSmith 实体生成模板(C#版)
如何获取JavaCard剩余空间
SCPlatform · 2012-01-12 · via 博客园 - SCPlatform

0x01应用场景

获取JavaCard卡内剩余空间,一方面是在评估一张卡的时候需要用到,另一方面是在应用个人化或者运行时需要用到。

例如:应用提供商为了保证自己的应用在卡内运行期间能够不受空间影响,一般会在个人化(安装应用)的时候先分配好需要用到的空间,以免空间被后来应用占用,导致运行失败。

0x02空间类型

卡内剩余空间包括获取卡内的剩余永久存储器(E2P or Flash),还有获取易失性存储器空间(RAM),这里的RAM分为两部分,一部分是在卡片复位时清零的内存CLEAR_ON_RESET,缩写为COR或者RTR(Clear_on_Reset Transient RAM);另一部分为应用在取消选择的时候清零的内存CLEAR_ON_DESELECT,缩写为COD或者DTR(Clear_on_Deselect Transient RAM)。本文将通过实例获取卡内的这三种存储器剩余空间。

0x03获取接口

对于获取JavaCard内可用空间,API提供了相应的接口JCSystem.getAvaliableMemory(byte memoryType) ,位于javacard.framework包下,如下所示,引用自JCAPI v2.2.2。 

 

getAvailableMemory

public static short getAvailableMemory(byte memoryType)
                                throws SystemException
Obtains the amount of memory of the specified type that is available to the applet. Note that implementation-dependent memory overhead structures may also use the same memory pool.

Notes:

  • The number of bytes returned is only an upper bound on the amount of memory available due to overhead requirements.
  • Allocation of CLEAR_ON_RESET transient objects may affect the amount of CLEAR_ON_DESELECT transient memory available.
  • Allocation of CLEAR_ON_DESELECT transient objects may affect the amount of CLEAR_ON_RESET transient memory available.
  • If the number of available bytes is greater than 32767, then this method returns 32767.
  • The returned count is not an indicator of the size of object which may be created since memory fragmentation is possible.
Parameters:
memoryType - the type of memory being queried. One of the MEMORY_TYPE_* constants defined above. See MEMORY_TYPE_PERSISTENT.
Returns:
the upper bound on available bytes of memory for the specified type
Throws:
SystemException - with the following reason codes:
  • SystemException.ILLEGAL_VALUE if memoryType is not a valid memory type.

  根据接口描述,如果可用字节数超过32767(0x3FFF),则只返回32767。那如何返回超过32767的空间,可参考本文后面的代码实例。

0x04代码实例

1.获取DTR剩余空间

 1     /**
 2      * 获取剩余MEMORY_TYPE_TRANSIENT_DESELECT空间
 3      * @return
 4      */
 5     public int getFreeDTR(){
 6         //首先取得剩余空间大小
 7         short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
 8         int allmemsize = memsize;
 9         //如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
10         while(memsize == (short)32767){
11             JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);//不存储返回的数组对象
12             memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
13             allmemsize += memsize;
14         }
15         return allmemsize;
16     }

 2.获取RTR剩余空间

 1     /**
 2      * 获取剩余的MEMORY_TYPE_TRANSIENT_RESET空间
 3      * @return
 4      */
 5     public int getFreeRTR(){
 6         //首先取得剩余空间大小
 7         short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
 8         int allmemsize = memsize;
 9         //如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
10         while(memsize == (short)32767){
11             JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_RESET);//不存储返回的数组对象
12             memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
13             allmemsize += memsize;
14         }
15         return allmemsize;
16     }

 3.获取E2P/Flash的剩余空间

 1     /**
 2      * 获取剩余的E2P/Flash空间,如果剩余空间大于0x3FFF,则此接口将创建数组,然后再获取新的剩余空间,
 3      * 数组对象头将占用几个字节(根据对象存储结构不一样,可能占用字节数不同,一般数组头为7字节),因此存在误差。
 4      * @return
 5      */
 6     public int getFreePersistent(){
 7         //首先取得剩余空间大小
 8         short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
 9         int allmemsize = memsize;
10         //如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
11         while(memsize == (short)32767){
12             byte[] tmp=new byte[memsize]; //不存储返回的数组对象
13             memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
14             allmemsize += memsize;
15         }
16         return allmemsize;
17     }

 注意

1.获取剩余空间的应用自身的代码需要占用部分空间,本例中的应用代码主468字节,存储在卡内空间为 278 字节.

2.DTR与RTR可能使用同一块区域。

3.以上代码在使用converter转成cap文件时需要加上支持int类型的选项,如果卡片本身不支持int,则代码中相应的地方需要做调整,譬如说如果卡内相应存储器空间大于0x3FFF时,可以将每次取得的值存储在apdubuffer中,一起返回到卡外,然后再计算。 

完整代码

  1 package GetFreeSpacePkg;
  2 
  3 import javacard.framework.APDU;
  4 import javacard.framework.ISO7816;
  5 import javacard.framework.Applet;
  6 import javacard.framework.ISOException;
  7 import javacard.framework.JCSystem;
  8 
  9 /**
 10  * 获取卡内剩余空间,包括E2P/Flash与RAM.
 11  * 对于E2P/Flash来说,如果卡内剩余空间超过0x3FFF,则此应用返回的数据会有较小的误差。
 12  * 测试命令:
 13  * 
 14  * 8000000000 //get DTR
 15  * 8001000000 //get RTR
 16  * 8002000000 //get E2P/Flash
 17  *  
 18  * @author SCPlatform@outlook.com
 19  */
 20 public class GetFreeSpaceApplet extends Applet {
 21     public static void install(byte[] bArray, short bOffset, byte bLength) {
 22         new GetFreeSpaceApplet().register(bArray, (short) (bOffset + 1),bArray[bOffset]);
 23     }
 24 
 25     public void process(APDU apdu) {
 26         if (selectingApplet()) {
 27             return;
 28         }
 29         
 30         byte[] buf = apdu.getBuffer();
 31         int iFreeSpace=0; 
 32         switch (buf[ISO7816.OFFSET_INS]) {
 33         case (byte) 0x00://DTR
 34             iFreeSpace = getFreeDTR();
 35             break;
 36         case (byte) 0x01://RTR
 37             iFreeSpace = getFreeRTR();
 38             break;
 39         case (byte) 0x02://persistent
 40             iFreeSpace = getFreePersistent();
 41             break;
 42         default:
 43             ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
 44         }
 45         JCSystem.requestObjectDeletion();
 46         buf[3]=(byte)(iFreeSpace);
 47         buf[2]=(byte)(iFreeSpace>>8);
 48         buf[1]=(byte)(iFreeSpace>>16);
 49         buf[0]=(byte)(iFreeSpace>>24);
 50         apdu.setOutgoingAndSend((short)0, (short)4);
 51     }
 52     /**
 53      * 获取剩余MEMORY_TYPE_TRANSIENT_DESELECT空间
 54      * @return
 55      */
 56     public int getFreeDTR(){
 57         //首先取得剩余空间大小
 58         short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
 59         int allmemsize = memsize;
 60         //如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
 61         while(memsize == (short)32767){
 62             JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);//不存储返回的数组对象
 63             memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
 64             allmemsize += memsize;
 65         }
 66         return allmemsize;
 67     }
 68     
 69     /**
 70      * 获取剩余的MEMORY_TYPE_TRANSIENT_RESET空间
 71      * @return
 72      */
 73     public int getFreeRTR(){
 74         //首先取得剩余空间大小
 75         short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
 76         int allmemsize = memsize;
 77         //如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
 78         while(memsize == (short)32767){
 79             JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_RESET);//不存储返回的数组对象
 80             memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
 81             allmemsize += memsize;
 82         }
 83         return allmemsize;
 84     }
 85     
 86     /**
 87      * 获取剩余的E2P/Flash空间,如果剩余空间大于0x3FFF,则此接口将创建数组,然后再获取新的剩余空间,
 88      * 数组对象头将占用几个字节(根据对象存储结构不一样,可能占用字节数不同,一般数组头为7字节),因此存在误差。
 89      * @return
 90      */
 91     public int getFreePersistent(){
 92         //首先取得剩余空间大小
 93         short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
 94         int allmemsize = memsize;
 95         //如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
 96         while(memsize == (short)32767){
 97             byte[] tmp=new byte[memsize]; //不存储返回的数组对象
 98             memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
 99             allmemsize += memsize;
100         }
101         return allmemsize;
102     }
103 }

 0x05资料参考

1.Application Programming Interface Java Card™ Platform, Version 2.2.2