我为什么要使用" setSeed()"在我的Java卡程序?

时间:2015-02-22 12:23:13

标签: java random javacard random-seed

我编写了以下程序,在我的java卡中生成 16字节随机数。我使用apdu缓冲区作为种子:

public class RandomNumber extends Applet {

    private RandomData rngRandom;
    public static byte[] testArray1=new byte[16];

    private RandomNumber() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new RandomNumber().register();


    }

    public void process(APDU arg0) throws ISOException {

        byte[] buffer=arg0.getBuffer();
        // CREATE RNG OBJECT
        m_rngRandom = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
        m_rngRandom.setSeed(buffer, (short)0,(short)buffer.length );
        // GENERATE RANDOM BLOCK WITH 16 BYTES
        m_rngRandom.generateData(testArray1, (short) 0, (short)16); 

        Util.arrayCopyNonAtomic(testArray1, (short)0, buffer, (short)0,(short) testArray1.length);
        arg0.setOutgoingAndSend((short)0, (short)16);

    }

}

我将其转换并将其上传到我的卡上,其中AID = 01020304050607080900。 这对我来说可以。我重复发送SELECT APDU命令(所以我有一个固定的种子),我收到不同的数字作为随机输出:

OpenSC: opensc-tool -s 00a404000b0102030405060708090000
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):
C2 BA 8E 75 67 A4 5F 16 1C 82 BE 98 5B 95 88 23 ...ug._.....[..#

OpenSC: opensc-tool -s 00a404000b0102030405060708090000
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):
8C 95 C3 AC 26 91 97 68 84 57 D8 E9 A5 5A CF 49 ....&..h.W...Z.I

OpenSC: opensc-tool -s 00a404000b0102030405060708090000
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):
34 2C 20 17 80 D1 EC 10 E3 E3 08 E2 DB 82 39 CB 4, ...........9.

OpenSC: opensc-tool -s 00a404000b0102030405060708090000
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):
E1 F6 60 B9 07 34 F2 46 A2 B0 43 19 E3 37 35 5D ..`..4.F..C..75]

OpenSC:

现在,我从程序中删除setSeed()方法,然后上传新的 cap 文件。输出仍然是随机的:

OpenSC: opensc-tool -s 00a404000b0102030405060708090000
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):
67 1E AE 42 29 ED 4E EE 0E 8F 57 86 C8 8F A3 FF g..B).N...W.....

OpenSC: opensc-tool -s 00a404000b0102030405060708090000
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):
B8 D9 7F 0A EB 3B C3 E4 E0 4C 8F 04 95 E2 1B F4 .....;...L......

OpenSC: opensc-tool -s 00a404000b0102030405060708090000
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):
F3 34 88 E4 C2 B1 E9 D1 77 E3 69 4C 91 21 13 69 .4......w.iL.!.i

OpenSC: opensc-tool -s 00a404000b0102030405060708090000
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):
69 46 C7 0E C9 81 9E 48 AF 5E D4 6A 28 BF 42 E4 iF.....H.^.j(.B.

我的问题:

如上所述,在这两种情况下(使用setSeed()或不使用它),我的输出是一个随机数组。那么为什么我需要使用这种方法呢?

当我使用固定种子时,我是否应该收到相同的结果?如果是这样,我为什么不这样做?

固定种子与每代一次似乎有什么区别?

当我不使用这种方法时种子是什么?

2 个答案:

答案 0 :(得分:5)

setSeed()补充而不是替换Java Card RandomData对象的种子,就像Java SE上的SecureRandom一样。但是,在3.0.4之前的API中没有明确说明这一点。

但是,如果您阅读常量ALG_PSEUDO_RANDOM的文字,您将获得:

  

实用程序伪随机数生成算法。即使用相同的种子数据播种,该算法生成的随机数序列也不必相同。

至于setSeed方法,你不需要打电话如果你确实叫它我希望你能打电话它的源包含比发送到卡的APDU更多的熵。


一般来说,ALG_PSEUDO_RANDOMALG_SECURE_RANDOM的区别并不明确。 ALG_PSEUDO_RANDOM可能意味着该算法不像ALG_SECURE_RANDOM 那样安全,但它也可能意味着它是预播种确定性随机数生成器

ALG_SECURE_RANDOM也是如此。您可以读到它是芯片上通常可用的随机数发生器(在美白之后),或者它可能再次意味着它是预播种确定性随机数发生器(听起来很熟悉?)因为这通常被NIST等人认为更加安全。

如果您正确阅读,则表示两种算法可能实际上指向相同的实现。


总而言之,您没有看到太多差异(只是随机数据)的事实是预期的结果。如果在随机数生成器上运行完整的FIPS集,您可能会看到差异 - 这取决于实现。

编辑:由于ALG_PSEUDO_RANDOM的含义和种子不明确,我建议使用ALG_SECURE_RANDOM而不是ALG_PSEUDO_RANDOM来检索加密安全的随机数。

通常任一算法都是通过从CPU的安全处理器获得的随机性预先播种的。这意味着即使您提供种子,也无法使用算法创建相同的结果。这很好,因为你不知道实际的算法。如果你想这样做,你可能需要自己编写流密码,DRBG或KDF。

答案 1 :(得分:0)

我无法看到您的课程RandomData的来源,但我会假设您正在使用SecureRandomSecureRamdom总是随机播种,种子不能被强制取值(否则它不会安全!)。

以下摘自SecureRandom.setSeed() javadocs

  

public void setSeed(byte [] seed)

     

重新种植此随机对象。 给定的种子补充剂,而不是   替换现有种子。因此,永远不会保证重复呼叫   减少随机性。

如果你想要可重复的"随机性"您需要使用标准Random对象。