随机数据生成器applet返回“0x6F00”

时间:2015-04-28 11:22:16

标签: javacard

我编写了以下程序,使用两种不同的算法(ALG_SECURE_RANDOMALG_PSEUDO_RANDOM)生成不同长度的随机数。

APDU命令中的

P1P2按顺序指定算法和随机长度。

  • P1 = 0X01:ALG_SECURE_RANDOM
  • P1 = 0X02:ALG_PSEUDO_RANDOM
  • P2 =随机数长度

    公共类RandGen扩展了Applet {

    byte[] generatedArray;
    byte[] generatedRandom;
    
    RandomData randomDataSecure = RandomData
            .getInstance(RandomData.ALG_SECURE_RANDOM);
    RandomData randomDataPseudo = RandomData
            .getInstance(RandomData.ALG_PSEUDO_RANDOM);
    
    private RandGen() {
    }
    
    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new RandGen().register();
    }
    
    public void process(APDU apdu) throws ISOException {
    
        if (selectingApplet()) {
            return;
        }
    
        byte[] buffer = apdu.getBuffer();
    
        generatedArray = JCSystem.makeTransientByteArray(
                (short) buffer[ISO7816.OFFSET_P2], JCSystem.CLEAR_ON_DESELECT);
    
        switch (buffer[ISO7816.OFFSET_P1]) {
        case (0x01):
            generatedRandom = secureRandomGenerator(apdu);
            break;
    
        case (0x02):
            generatedRandom = pseudoRandomGenerator(apdu);
            break;
    
        default:
            return;
        }
    
        Util.arrayCopyNonAtomic(generatedRandom, (short) 0, buffer, (short) 0,
                (short) ISO7816.OFFSET_P2);
        apdu.setOutgoingAndSend((short) 0, (short) ISO7816.OFFSET_P2);
    }
    
    public byte[] secureRandomGenerator(APDU apdu) {
        byte[] buffer = apdu.getBuffer();
        randomDataSecure.generateData(generatedArray, (short) 0,
                (short) buffer[ISO7816.OFFSET_P2]);
        return generatedArray;
    }
    
    public byte[] pseudoRandomGenerator(APDU apdu) {
        byte[] buffer = apdu.getBuffer();
        randomDataPseudo.generateData(generatedArray, (short) 0,
                (short) buffer[ISO7816.OFFSET_P2]);
        return generatedArray;
    }
    

    }

CAP文件已成功生成并上传到卡上,但当我向卡发送APDU命令时,我收到0X6F00状态字:

OSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00000202
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 02 02
Received (SW1=0x90, SW2=0x00)

OSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00000102
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 01 02
Received (SW1=0x6F, SW2=0x00) 

我的applet有什么问题吗?

更新

根据亲爱的@ Vojta的回答,我替换

Util.arrayCopyNonAtomic(generatedRandom, (short) 0, buffer, (short) 0,
        (short) ISO7816.OFFSET_P2);
apdu.setOutgoingAndSend((short) 0, (short) ISO7816.OFFSET_P2);

使用process()方法中的以下行:

    Util.arrayCopyNonAtomic(generatedRandom, (short) 0, buffer, (short) 0,
            (short) buffer[ISO7816.OFFSET_P2]);
    apdu.setOutgoingAndSend((short) 0, (short) buffer[ISO7816.OFFSET_P2]);

现在我在 OpenSC-Tool 输出中有一个奇怪的输出:

安全随机生成器:

OSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00000110
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 01 10
Received (SW1=0x90, SW2=0x00):
B8 1F 80 25 A2 8E 25 30 F8 22 F8 40 0F AE B0 6C ...%..%0.".@...l
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00                                  .....

OSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00000110
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 01 10
Received (SW1=0x6F, SW2=0x00)

OSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00000110
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 01 10
Received (SW1=0x90, SW2=0x00):
F6 45 A9 0C 0C 3B 3A 5A 5F DC A8 36 .E...;:Z_..6

伪随机生成器:

OSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00000210
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 02 10
Received (SW1=0x90, SW2=0x00):
37 FD FC 67 EB 9E 21 00 6B E9 44 A7 21 3F 31 9A 7..g..!.k.D.!?1.
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00                            .......

OSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00000210
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 02 10
Received (SW1=0x6F, SW2=0x00)

OSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00000210
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 02 10
Received (SW1=0x90, SW2=0x00):
72 FE 48 1B 9A A0 BD 2D DF F9 E7 F8 58 CF B7 C0 r.H....-....X...
00 00 00 00 00 00 00 00 00 00 00                ...........

为什么单个命令的输出不同?

2 个答案:

答案 0 :(得分:3)

您的代码中存在一些小错误。你想要

Util.arrayCopyNonAtomic(generatedRandom, (short) 0, buffer, (short) 0,
            (short) buffer[ISO7816.OFFSET_P2]);

而不是

Util.arrayCopyNonAtomic(generatedRandom, (short) 0, buffer, (short) 0,
            (short) ISO7816.OFFSET_P2);

一般规则:始终使用try-catch块包围process方法的内容,并根据异常的类型和原因设置状态字。否则你只得到6F00并且你不知道到底发生了什么。如果您遵循此规则,则会知道ArrayIndexOutOfBoundsException被抛出。

回答更新:

奇怪的输出是由事实造成的,

Util.arrayCopyNonAtomic(generatedRandom, (short) 0, buffer, (short) 0,
            (short) buffer[ISO7816.OFFSET_P2]);
apdu.setOutgoingAndSend((short) 0, (short) buffer[ISO7816.OFFSET_P2]);

用一些随机值覆盖buffer[ISO7816.OFFSET_P2],然后在下一行使用该值。您应该在buffer[ISO7816.OFFSET_P2]方法的开头将process存储在RAM中:

final byte p2 = buffer[ISO7816.OFFSET_P2];

回答以下评论:

由于将byte投射到short,因此P2> = 0x80会遇到麻烦。不幸的是,JavaCard将字节处理为有符号,这就是为什么P2> = 0x80的长度为负的原因。你可以通过以下方式轻松避免这种情况:

final short outputLen = (short) (buffer[ISO7816.OFFSET_P2] & 0xFF);

答案 1 :(得分:0)

命令不受支持 你有错误的指示加在一起。