Java Card中的内存分配

4

我有一张Java Card智能卡,需要评估可用的EEPROM。

为此,我使用函数JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT)。由于这个函数的返回值是一个short,在不分配任何数据的情况下,我获得了值0x7FFF。为了解决这个问题,我通过new byte[(short) 0x7FFF]方式创建byte数组,来推断可用的持久存储器。

如果我创建两个数组:

arr1 = new byte[(short) 0x7FFF];
arr2 = new byte[(short) 0x7FFF];

然后,根据JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT),它会保留0x1144字节的可用内存。因此,如果我总结一下,就是32767 * 2 + 4420 = 69954个字节可用。

但当我改变数组的大小时:

arr1 = new byte[(short) 0x7FFF];
arr2 = new byte[(short) 0x6FFF];

然后它会保留 0x2244 字节的可用内存。因此,如果我进行求和,这意味着有70210字节可用。

另一个例子:

arr1 = new byte[(short) 0x7FFF];
arr2 = new byte[(short) 0x5FFF];

这段代码使用了 0x3344 字节的可用内存,因此如果进行求和,意味着有 70466 字节可用。

即使差距微不足道,为什么会存在这些差异?(70210 和 70466 的区别)

同样地,我想测试一下在一个 Applet 中可以分配多少个 AESKey。因此,我尝试按照之前所述的方式来查找可用内存,但这次是针对 AESKey 数组。

在同一张卡上,当我以以下方式创建一个 AESKey 数组时:

arr = new AESKey[(short) 0x03E8];
for (short i = 0x0000; i < 0x03E8; i++) {
  arr[i] = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,  KeyBuilder.LENGTH_AES_256, false);
}

我创建了一个包含一千个 256 位 AESKey 的数组。我认为它需要 32Ko,但是方法 JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT) 表明只有 0x0022 字节可用。为什么会出现这种结果?

如果我只测试一半的密钥(例如 500):

arr = new AESKey[(short) 0x01F4];
for (short i = 0x0000; i < 0x01F4; i++) {
   arr[i] = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,  KeyBuilder.LENGTH_AES_256, false);
}

方法 JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT) 表示有 0x55EE(21998)字节可用:我绝对看不出与创建1000个密钥时的情况有何关系,如果可用EEPROM大约为70Ko,就像我之前解释的那样...

有人能详细描述在Java Card中如何分配内存以解释上述结果吗?

2个回答

3
这是几个原因:
  • 存在对象分配开销;
  • 可能存在数据对齐的开销;
  • 可能存在内存碎片化的开销;
  • 对于密钥,可能需要开销来保持其安全。
所有这些问题都会减少可用内存的数量。在这方面,您应该将getAvailableMemory视为可用内存的最大值粗略指示
所需的开销量取决于Java Card运行时。

通过实验,奇怪的是,在我的智能卡上,一个256位的对象AESKey在EEPROM中占用大约90个字节(几乎是密钥大小的三倍!)。我通过分配AESKey数组并调用函数JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT)找到了它。我猜这个值会根据智能卡制造商而有所不同? - Raoul722

2
很简单地说:
Java Card 不擅长存储数组/它需要额外的数据。因此,如果您用 x 字节填充一个字节数组以达到 0x7FFF 的阈值以下,则数组在内部存储数据时将需要多于 x 字节的空间,因此您会注意到差异。
如果您使用的是 JCOP 卡,则可以通过使用UtilX.getAvailableMemory() 来避免此问题。
要了解更多信息,请阅读:http://ruimtools.com/doc.php?doc=jc_best 上关于减少 EEPROM 消耗的部分(但某些部分已过时)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接