如何获取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。 

 

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

转载于:https://www.cnblogs.com/SCPlatform/archive/2012/01/12/5125200.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/475316.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 1474. 删除链表 M 个节点之后的 N 个节点

文章目录1. 题目2. 解题1. 题目 给定链表 head 和两个整数 m 和 n. 遍历该链表并按照如下方式删除节点: 开始时以头节点作为当前节点. 保留以当前节点开始的前 m 个节点. 删除接下来的 n 个节点. 重复步骤 2 和 3, 直到到达链表结尾. 在删除了指定结点之后, 返回修改过后的链…

mac找不到mysql_mac找不到mysql

出现问题:macbook安装好mysql,并按照各路大神的说明进行了以下配置。打开Terminal,输入:vim .bash_profile进入编辑界面,添加以下内容:export PATH$PATH:/usr/local/mysql/bin按下esc键,输入 :w…

一个 SQL 同时验证帐号是否存在、密码是否正确

出处:http://www.cnblogs.com/jacklondon/archive/2012/01/13/2321686.html近日偶尔看到一个很巧妙的 SQL 技巧,一个简单的 SQL 同时验证帐号是否存在、密码是否正确。之前从未曾想过这么做,也未曾见过别人这么做。虽是奇技淫巧,却…

LeetCode 1427. 字符串的左右移

文章目录1. 题目2. 解题1. 题目 给定一个包含小写英文字母的字符串 s 以及一个矩阵 shift,其中 shift[i] [direction, amount]: direction 可以为 0 (表示左移)或 1 (表示右移)。 amount 表示 s 左右移的…

修改mysql数据库字符集_修改及查看mysql数据库的字符集

Liunx下修改MySQL字符集:1.查找MySQL的cnf文件的位置find / -iname *.cnf -print/usr/share/mysql/my-innodb-heavy-4G.cnf/usr/share/mysql/my-large.cnf/usr/share/mysql/my-small.cnf/usr/share/mysql/my-medium.cnf/usr/share/mysql/my-huge.cnf/usr/share/texm…

生成简单的Makefile文件(Python实现)

在linux下写几个测试程序,还要一行行的输入g命令进行编译,当经常改测试代码的时候,那一次次的敲(或者一次次的上线箭头选)也感觉不爽,不如make来的快。用Makefile的好处就不用多说了,这里我写了…

LeetCode 800. 相似 RGB 颜色

文章目录1. 题目2. 解题2.1 暴力枚举2.2 独立枚举1. 题目 RGB 颜色用十六进制来表示的话,每个大写字母都代表了某个从 0 到 f 的 16 进制数。 RGB 颜色 “#AABBCC” 可以简写成 “#ABC” 。例如,"#15c" 其实是 “#1155cc” 的简写。 现在&a…

mysql 图片base64_关于图片的Base64编码

什么是Base64编码Base64编码是一种图片处理格式,通过特定的算法将图片编码成一长串字符串,在页面上显示的时候,可以用该字符串来代替图片的url属性。base64编码就是长得像下面这样子的代码:thunder://QUFodHRwOi8vd3d3LmJhaWR1LmN…

LeetCode 243. 最短单词距离

文章目录1. 题目2. 解题1. 题目 给定一个单词列表和两个单词 word1 和 word2,返回列表中这两个单词之间的最短距离。 示例: 假设 words ["practice", "makes", "perfect", "coding", "makes"] 输入: word1 “…

mysql load character_mysql load data Invalid utf8mb4 character string: ”

使用mysql的 load data 导入数据到 数据库中:LOAD DATA LOCAL INFILE /tmp/2982/20200424/user.csvINTO TABLE t_user CHARACTER SET utf8mb4 FIELDS TERMINATED BY ,LINES TERMINATED BY \r\nIGNORE 1 LINES(userName, userNo, age, homeAddr)SET province 浙江省…

LeetCode 1426. 数元素(哈希set)

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 arr, 对于元素 x ,只有当 x 1 也在数组 arr 里时,才能记为 1 个数。 如果数组 arr 里有重复的数,每个重复的数单独计算。 示例 1: 输入:arr [1,2,3] …

mysql 默认page大小_MySQL innodb_page_size

原标题:MySQL innodb_page_size墨墨导读:Page是MySQL Innodb存储的最基本结构,也是Innodb磁盘管理的最小单位,了解page的一些特性,可以更容易理解MySQL。innodb_page_size作为innodb和OS交互单位。文件系统对文件的buf…

控制台中使用cstring和string

VC 6.0 控制台&#xff1a; 1、使用string   #include <string>using namespace std; 2、使用 cstring 首先设置"在共享 DLL 中使用 MFC"&#xff0c;然后 #include <afx.h>VS2003 控制台 1、使用string using namespace std; 2、使用csting   #incl…

LeetCode 266. 回文排列(计数)

文章目录1. 题目2. 解题1. 题目 给定一个字符串&#xff0c;判断该字符串中是否可以通过重新排列组合&#xff0c;形成一个回文字符串。 示例 1&#xff1a; 输入: "code" 输出: false示例 2&#xff1a; 输入: "aab" 输出: true示例 3&#xff1a; 输入…

centos6.5装mysql好难_CentOS6.5 下MySQL傻瓜式安装

为了为服务器上装mysql我先在虚拟机上练习了一下特此记录并分享;注:参考文章https://www.cnblogs.com/xiaoluo501395377/archive/2013/04/07/3003278.html1.测系统是否自带安装mysql[rootwzpbk~]#rpm -qa | grep mysql  // 这个命令就会查看该操作系统上是否已经安装了mysql数…

Java 中实现定时服务 在ssh框架中跟普通工程里面创建的方式

http://www.iteye.com/topic/1119730转载于:https://www.cnblogs.com/caixiaoqiu/archive/2012/02/03/2336818.html

LeetCode 1150. 检查一个数是否在数组中占绝大多数(二分查找)

文章目录1. 题目2. 解题2.1 暴力2.2 二分查找1. 题目 给出一个按 非递减 顺序排列的数组 nums&#xff0c;和一个目标数值 target。 假如数组 nums 中绝大多数元素的数值都等于 target&#xff0c;则返回 True&#xff0c;否则请返回 False。 所谓占绝大多数&#xff0c;是指…

mysql 常用注入命令_SQL注入常用命令

1. 数据库查询版本Mssql select versionMysql select vresion()/select versionoracle select banner from &#xffe5;versionPostgresql select version()2. 数据库常用命令库操作连接数据库 mysql -u 用户名 -p创建数据库&#xff1a;create database 数据库名称、删除数据…

VirtualBox的Linux虚拟机访问Windows7的文件

第一步&#xff1a; 安装 VirtualBox 增强工具 点击确定&#xff0c;稍等片刻&#xff0c;VirtualBox 的增强功能就可以安装完毕。 第2步&#xff1a;设置要共享给Linux 虚拟机的文件夹&#xff08;目录&#xff09; 点击右下角的“分配数据空间” 点击“添加” 选择要共享的路…

LeetCode 1118. 一月有多少天(闰年判断)

文章目录1. 题目2. 解题1. 题目 指定年份 Y 和月份 M&#xff0c;请你帮忙计算出该月一共有多少天。 示例 1&#xff1a; 输入&#xff1a;Y 1992, M 7 输出&#xff1a;31示例 2&#xff1a; 输入&#xff1a;Y 2000, M 2 输出&#xff1a;29示例 3&#xff1a; 输入&am…