欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > java >内容正文

java

如何获取JavaCard剩余空间

发布时间:2023/12/20 java 71 豆豆
生活随笔 收集整理的这篇文章主要介绍了 如何获取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

创作挑战赛新人创作奖励来咯,坚持创作打卡瓜分现金大奖

总结

以上是生活随笔为你收集整理的如何获取JavaCard剩余空间的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。