【问题标题】:How to store data larger than 128 byte in JavaCard如何在 JavaCard 中存储大于 128 字节的数据
【发布时间】:2016-01-12 06:26:16
【问题描述】:

我无法在字节数组中写入索引超过 128 的数据。 代码如下。

private void Write1(APDU apdu) throws ISOException
{
    apdu.setIncomingAndReceive();
    byte[] apduBuffer = apdu.getBuffer();
    byte j = (byte)apduBuffer[4];       // Return incoming bytes lets take 160
    Buffer1 = new byte[j];              // initialize a array with size 160
    for (byte i=0; i<j; i++)
        Buffer1[(byte)i] = (byte)apduBuffer[5+i];
}

它给了我错误 6F 00(这意味着到达文件结尾)。

我正在使用:

  • 智能卡类型=联系人卡
  • 使用 java 卡 2.2.2 和 jcop 使用 apdu

【问题讨论】:

    标签: applet byte smartcard javacard apdu


    【解决方案1】:

    您的代码包含几个问题:

    1. 正如 'pst' 已经指出的那样,您使用的是签名的 byte 值,该值仅适用于 128 - 请改用 short

    2. 您在每次调用 Write1 方法时都会创建一个新缓冲区 Buffer1。在 JavaCard 上通常没有自动垃圾收集 - 因此内存分配应该只在安装应用程序时进行一次。如果您只想处理 adpu 缓冲区中的数据,只需从那里使用它。如果你想将数据从一个字节数组复制到另一个更好的使用javacard.framework.Util.arrayCopy(..)

    3. 您正在调用apdu.setIncomingAndReceive();,但忽略返回值。返回值给出了可以读取的数据字节数。

    以下代码来自 API 文档并显示了常用方式:

    short bytesLeft = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
    if (bytesLeft < (short)55) ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
    short readCount = apdu.setIncomingAndReceive();
    while ( bytesLeft > 0){
    
         // process bytes in buffer[5] to buffer[readCount+4];
    
         bytesLeft -= readCount;
         readCount = apdu.receiveBytes ( ISO7816.OFFSET_CDATA );
    }
    

    【讨论】:

    • 感谢您的回答。我尝试了相同的方法,但它不会写入或接受超过 255 的值。
    • 这是设计使然。一个标准的 APDU 不能大于 255 字节。只有具有扩展 APDU 支持的卡才能处理大于该值的 APDU。实际上,最大数据长度通常甚至小于 255 字节,因为必须考虑为安全通道封装安全有效负载。
    • if (bytesLeft &lt; (short)55) ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );中,55是从哪里来的?
    【解决方案2】:
    short j = (short) apdu_buffer[ISO7816.OFFSET_LC] & 0xFF
    

    【讨论】:

      【解决方案3】:

      详细说明 pst 的答案。一个字节有 2^8 位数字,或者更确切地说是 256。但是如果您使用带符号的数字,它们将在一个循环中工作。所以,128 实际上是 -128,129 是 -127,依此类推。

      【讨论】:

      • 有没有办法使用无符号字节
      【解决方案4】:

      更新:虽然以下答案对于普通 Java 是“有效的”,但请参阅 Roberts 的答案以获取 Java Card 特定信息以及其他问题/方法。


      在 Java 中,byte 的值在 [-128, 127] 范围内,因此,当您说“160”时,这不是代码真正提供给您的 :)

      也许你想使用:

      int j = apduBuffer[4] & 0xFF;
      

      将值apduBuffer[4]“向上转换”为int,同时将原始字节数据视为无符号值。

      同样,i 也应该是 int(以避免讨厌的永远溢出和循环的错误),System.arraycopy 方法也可以很方便...

      (我不知道这是否是唯一/真正的问题——或者上述是否是Java Card 上的可行解决方案——但它肯定是一个问题并且与提到了“128 限制”。)

      编码愉快。

      【讨论】:

      • 很多 JavaCard 实现不支持 int 数据类型。因此使用short 将是最好的方法。此外,JavaCard 环境中没有可用的 System.arrayCopy()。
      • @Robert 感谢您提供的信息。你的答案肯定更适合 Java Card :)
      猜你喜欢
      • 2011-12-26
      • 2011-04-23
      • 2017-07-19
      • 2017-04-03
      • 1970-01-01
      • 2014-04-24
      • 1970-01-01
      • 2011-05-25
      • 2017-12-21
      相关资源
      最近更新 更多