0

我有一个基于 android 的 NFC 应用程序,它发送一个哈希作为 apdu 答案。这是我在我的 Android 应用程序中用于发送哈希的代码:

@Override
    public byte[] processCommandApdu(byte[] arg0, Bundle arg1) {

        String hash = "e68d3f574009cbbe011150263634c5c0";

        return hash.getBytes(Charset.forName("UTF-8"));

    }

现在,当我在 Arduino 方面收到它时,我得到了以下 RAW 数据:

10154561005110253555248485799989810148494949534850255255255255255255255255255

我如何从中取回哈希?

这就是我现在所拥有的,但它显然不起作用:

        uint8_t response[32];

        uint8_t responseLength = sizeof(response);

        if (nfc.inDataExchange(message, sizeof(message), response, &responseLength)) {

            Serial.print("RAW: ");
            for (int i = 0; i < sizeof(response); i++) {
                Serial.print(response[i]);
            }

            Serial.println(" ");

            char buffer[32];
            itoa((int)response,buffer,8);

            Serial.print("ITOA: ");
            for (int i = 0; i < sizeof(buffer); i++) {
                Serial.print(buffer[i]);
            }

            Serial.println(" ");
       }

这是上面代码的串行输出:

RAW: 10154561005110253555248485799989810148494949534850255255255255255255255255255 
ITOA: 4253   µ      + 
  3ü       R    

哈!!!!

4

2 回答 2

1

三个建议,尽管它们都没有真正解释为什么最后几个字节被截断:

  1. 不要将十六进制哈希表示形式转换为字符串,以便以后以 UTF-8 编码发送这些字符。直接将哈希作为字节发送会更有效(并且解码工作更少):

    @Override
    public byte[] processCommandApdu(byte[] arg0, Bundle arg1) {
        byte[] hash = {
                (byte)0xe6, (byte)0x8d, (byte)0x3f, (byte)0x57,
                (byte)0x40, (byte)0x09, (byte)0xcb, (byte)0xbe,
                (byte)0x01, (byte)0x11, (byte)0x50, (byte)0x26,
                (byte)0x36, (byte)0x34, (byte)0xc5, (byte)0xc0
        };
    
        return hash;
    }
    

    如果您已经将哈希作为十六进制字符串,我建议您先将其转换为 Android 端的字节表示。

  2. 使用 HCE 时,您应该坚持使用 ISO/IEC 7816-4 APDU,而不仅仅是发送随机数据。一个命令 APDU(短格式)包括以下内容:

    +----------+----------+----------+----------+----------+------------+----------+
    | CLA      | INS      | P1       | P2       | Lc       | DATA       | Le       |
    | (1 Byte) | (1 Byte) | (1 Byte) | (1 Byte) | (1 Byte) | (Lc Bytes) | (1 Byte) |
    +----------+----------+----------+----------+----------+------------+----------+
    

    其中 Lc 编码 DATA 的字节数。如果 DATA 为空,则 Lc 也为空。Le 将预期的字节数编码为响应(Le = 0x00 的特殊情况,这意味着预期的响应字节数为 256。

    响应 APDU(这是您在 中作为返回值发送的内容processCommandApdu)如下所示:

    +----------+----------+----------+
    | DATA     | SW1      | SW2      |
    | (n Byte) | (1 Byte) | (1 Byte) |
    +----------+----------+----------+
    

    DATA 是响应数据。SW1 和 SW2 形成响应状态字(通常 SW1 = 0x90,SW2 = 0x00 表示成功)。请注意,SW1 和 SW2 是必需的。

  3. 在迭代inDataExchange使用该函数 ( responseLength) 提供的响应长度而不是最大缓冲区长度的响应时:

    for (int i = 0; i < responseLength; ++i) {
        ...
    }
    

    此外,我建议您提供一个超过最大预期响应长度的缓冲区。(特别是在您对 32 个字符的字符串使用 UTF-8 编码的情况下,这可能(对于某些字符)导致超过 32 个字节。)

于 2013-11-26T08:15:59.070 回答
-1

好的,所以我想出了我的答案。我不需要它。我可以将 RAW 输入类型转换为 char 并获得我需要的内容:

            Serial.print("TYPECASTED RAW: ");
            for (int i = 0; i < sizeof(response); i++) {
                Serial.print((char)response[i]);
            }

            Serial.println(" ");

那输出:

e68d3f574009cbbe0111502ÿÿÿÿÿÿÿÿÿ

现在我只是想知道为什么最后 9 个字符被替换为 255?

于 2013-11-26T04:01:19.463 回答