如何获取JavaCard剩余空间
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。
getAvailableMemorypublic static short getAvailableMemory(byte memoryType)
|
根据接口描述,如果可用字节数超过32767(0x3FFF),则只返回32767。那如何返回超过32767的空间,可参考本文后面的代码实例。
0x04代码实例
1.获取DTR剩余空间
/**
* 获取剩余MEMORY_TYPE_TRANSIENT_DESELECT空间
* @return
*/
public int getFreeDTR(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);//不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
allmemsize += memsize;
}
return allmemsize;
}
2.获取RTR剩余空间
/**
* 获取剩余的MEMORY_TYPE_TRANSIENT_RESET空间
* @return
*/
public int getFreeRTR(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_RESET);//不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
allmemsize += memsize;
}
return allmemsize;
}
3.获取E2P/Flash的剩余空间
/**
* 获取剩余的E2P/Flash空间,如果剩余空间大于0x3FFF,则此接口将创建数组,然后再获取新的剩余空间,
* 数组对象头将占用几个字节(根据对象存储结构不一样,可能占用字节数不同,一般数组头为7字节),因此存在误差。
* @return
*/
public int getFreePersistent(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
byte[] tmp=new byte[memsize]; //不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
allmemsize += memsize;
}
return allmemsize;
}
注意
1.获取剩余空间的应用自身的代码需要占用部分空间,本例中的应用代码主468字节,存储在卡内空间为 278 字节.
2.DTR与RTR可能使用同一块区域。
3.以上代码在使用converter转成cap文件时需要加上支持int类型的选项,如果卡片本身不支持int,则代码中相应的地方需要做调整,譬如说如果卡内相应存储器空间大于0x3FFF时,可以将每次取得的值存储在apdubuffer中,一起返回到卡外,然后再计算。
完整代码
package GetFreeSpacePkg; import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacard.framework.JCSystem; /**
* 获取卡内剩余空间,包括E2P/Flash与RAM.
* 对于E2P/Flash来说,如果卡内剩余空间超过0x3FFF,则此应用返回的数据会有较小的误差。
* 测试命令:
*
* 8000000000 //get DTR
* 8001000000 //get RTR
* 8002000000 //get E2P/Flash
*
* @author SCPlatform@outlook.com
*/
public class GetFreeSpaceApplet extends Applet {
public static void install(byte[] bArray, short bOffset, byte bLength) {
new GetFreeSpaceApplet().register(bArray, (short) (bOffset + 1),bArray[bOffset]);
} public void process(APDU apdu) {
if (selectingApplet()) {
return;
} byte[] buf = apdu.getBuffer();
int iFreeSpace=0;
switch (buf[ISO7816.OFFSET_INS]) {
case (byte) 0x00://DTR
iFreeSpace = getFreeDTR();
break;
case (byte) 0x01://RTR
iFreeSpace = getFreeRTR();
break;
case (byte) 0x02://persistent
iFreeSpace = getFreePersistent();
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
JCSystem.requestObjectDeletion();
buf[3]=(byte)(iFreeSpace);
buf[2]=(byte)(iFreeSpace>>8);
buf[1]=(byte)(iFreeSpace>>16);
buf[0]=(byte)(iFreeSpace>>24);
apdu.setOutgoingAndSend((short)0, (short)4);
}
/**
* 获取剩余MEMORY_TYPE_TRANSIENT_DESELECT空间
* @return
*/
public int getFreeDTR(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);//不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
allmemsize += memsize;
}
return allmemsize;
} /**
* 获取剩余的MEMORY_TYPE_TRANSIENT_RESET空间
* @return
*/
public int getFreeRTR(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_RESET);//不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
allmemsize += memsize;
}
return allmemsize;
} /**
* 获取剩余的E2P/Flash空间,如果剩余空间大于0x3FFF,则此接口将创建数组,然后再获取新的剩余空间,
* 数组对象头将占用几个字节(根据对象存储结构不一样,可能占用字节数不同,一般数组头为7字节),因此存在误差。
* @return
*/
public int getFreePersistent(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
byte[] tmp=new byte[memsize]; //不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
allmemsize += memsize;
}
return allmemsize;
}
}
0x05资料参考
1.Application Programming Interface Java Card™ Platform, Version 2.2.2
如何获取JavaCard剩余空间的更多相关文章
- Linux C++获取磁盘剩余空间和可用空间
完整源码 #include <sys/statfs.h> #include <string> #include <iostream> #include <li ...
- C# 获取磁盘剩余空间
drive.TotalFreeSpace单位为bit,根据需要除以1024 drive同时可以可以获取磁盘分区容量等 //单位MB public static long GetHardDiskSpac ...
- 两种方法,获取磁盘剩余空间--PYTHON
import ctypes import os import platform import sys def get_free_space_mb(folder): """ ...
- C# 获取电脑硬盘剩余空间
获取本地硬盘的所有剩余空间: 主要应用到System.IO类库的:Driveinfo.Directory,将model转换成json需要用到Newtonsoft.Json.JsonConvert.Se ...
- Android中StatFs获取系统/sdcard存储(剩余空间)大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- android计算每个目录剩余空间丶总空间以及SD卡剩余空间
ublic class MemorySpaceCheck { /** * 计算剩余空间 * @param path * @return */ public static String getAvail ...
- Android为TV端助力 计算每个目录剩余空间丶总空间以及SD卡剩余空间
ublic class MemorySpaceCheck { /** * 计算剩余空间 * @param path * @return */ public static String getAvail ...
- c# 读取所有磁盘的剩余空间
介绍: 有一个控制台命令是创建指定大小的空文件,因此我想制作一个一键填充剩余磁盘空间的坑人小程序. 想要填充剩余容量,就要先获取所有本地磁盘的剩余空间,这个程序就是用来做这个的. 项目类型为c#控制台 ...
- SQL Server自动化运维系列——监控磁盘剩余空间及SQL Server错误日志(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...
随机推荐
- IOS 控制器View的创建方式(方式的优先级 、view的延迟加载)
MJViewController的view的创建 的方式的优先级 控制器view的延迟加载 ● 控制器的view是延迟加载的:用到时再加载 ● 可以用isViewLoaded方法判断一个UIViewC ...
- 8--oop
oop-Python面向对象 Python的面向对象 面向对象编程 基础 共有私有 继承 组合,Mixin 魔法函数 魔法函数概述 构造类魔法函数 运算类魔法函数 1.面向对象概述(ObjectOri ...
- 如何着手学习一个新的PHP框架
如今的PHP框架层出不穷,名气也各不相同.如何快速掌握一种框架?看看本文吧~ 如今的PHP框架层出不穷,名气也各不相同.我不是这方面的专家,甚至不能熟练地使用其中的一种,所以就不作推荐了.这里我要讨论 ...
- java基础编程——获取栈中的最小元素
题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)). 题目代码 /** * Created by YuKai Fan on 2018/9 ...
- C++ 学习笔记 (七)继承与多态 virtual关键字的使用场景
在上一篇 C++ 学习笔记 (六) 继承- 子类与父类有同名函数,变量 中说了当父类子类有同名函数时在外部调用时如果不加父类名则会默认调用子类的函数.C++有函数重写的功能需要添加virtual关键字 ...
- 对比传统方式访问数据库和SpringData访问数据库
我们在写代码的时候应该一边写一边测试,这样的话可以尽快的找到错误,在代码写多了之后去找错误的话不容易给错误定位 传统方式访问数据库 1:创建一个Maven web项目 2:修改pom.xml为以下内容 ...
- GPIO实现I2C协议模拟(1)
最近需要用GPIO模拟I2C协议,如果是在Linux下面比较简单,但在Windows下面,是否有没Linux那么简单了. 索性自己对I2C协议还有一些了解,翻了SPEC并结合示波器量出的实际信号分析, ...
- PHP代码中出现中文乱码怎么办?
header("Content-type:text/html;charset=utf-8"); //加上这个就OK //示例 : class WechatController ex ...
- python面试题之介绍一下Python中webbrowser的用法
所属网站分类: 面试经典 > python 作者:外星人入侵 链接: http://www.pythonheidong.com/blog/article/13/ 来源:python黑洞网 www ...
- Bomb HDU - 3555 (数位DP)
Bomb HDU - 3555 (数位DP) The counter-terrorists found a time bomb in the dust. But this time the terro ...