简体   繁体   English

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

[英]Why should I use “setSeed()” in my java card program?

I wrote the below program to generate a 16 byte random number in my java card. 我编写了以下程序,在我的java卡中生成一个16字节的随机数。 I used the apdu buffer as the seed : 我使用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);

    }

}

I convert it and upload it on my card with AID= 01020304050607080900 . 我转换它并将其上传到我的卡上,AID = 01020304050607080900 It works fine for me. 这对我来说可以。 I send the SELECT APDU command repeatedly (so I have a fixed seed) and I receive different numbers as the random output : 我重复发送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:

Now, I remove the setSeed() method from my program and I upload the new cap file. 现在,我从程序中删除了setSeed()方法,并上传了新的cap文件。 The output is still random : 输出仍然是随机的:

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.

My question : 我的问题 :

As you see above, in both cases (using setSeed() or not using it) my output is a random array. 如上所示,在两种情况下(使用setSeed()或不使用它),我的输出是一个随机数组。 So why I need to use this method? 那么为什么我需要使用这种方法呢?

Shouldn't I receive the same outcome, when I use a fixed seed? 当我使用固定种子时,我不应该收到相同的结果吗? If so, why I don't? 如果是这样,我为什么不呢?

And what is the difference between a fixed seed and a one time seem per generation? 固定种子与每代一次似乎有什么区别?

And what is the seed when I don't use this method? 当我不使用这种方法时种子是什么?

setSeed() supplements rather than replaces the seed for a Java Card RandomData object, just like SecureRandom on Java SE. setSeed()补充而不是替换Java Card RandomData对象的种子,就像Java SE上的SecureRandom一样。 This is however not made explicit in the API up to 3.0.4. 然而,在3.0.4之前的API中没有明确说明这一点。

However, if you read the text of the constant ALG_PSEUDO_RANDOM you'll get: 但是,如果您阅读常量ALG_PSEUDO_RANDOM的文本,您将获得:

Utility pseudo-random number generation algorithms. 效用伪随机数生成算法。 The random number sequence generated by this algorithm need not be the same even if seeded with the same seed data. 即使用相同的种子数据播种,由该算法生成的随机数序列也不必相同。

As for the setSeed method, you don't need to call it and if you do call it I would hope that you would call it with a source containing more entropy than the APDU send to the card. 至于setSeed方法, 你不需要调用它如果你调用它,我希望你用一个包含比APDU发送到卡的熵更多的源来调用它。


In general the distinction of ALG_PSEUDO_RANDOM and ALG_SECURE_RANDOM is not that clear. 通常, ALG_PSEUDO_RANDOMALG_SECURE_RANDOM的区别并不明确。 ALG_PSEUDO_RANDOM could mean that the algorithm is not as secure as ALG_SECURE_RANDOM , but it could also mean that it is a pre-seeded deterministic random number generator . ALG_PSEUDO_RANDOM可能意味着该算法不如ALG_SECURE_RANDOM安全 ,但它也可能意味着它是预先播种的确定性随机数生成器

The same goes for ALG_SECURE_RANDOM . ALG_SECURE_RANDOM You could read that it is the random number generator that is generally available on the chip (after whitening) or it could again mean that it is a pre-seeded deterministic random number generator (sounds familiar?) because that's generally thought of to be more secure by the likes of NIST. 您可以读到它是芯片上通常可用的随机数发生器(在美白之后),或者它可能再次意味着它是预先播种的确定性随机数发生器 (听起来很熟悉?)因为通常认为它更多由NIST等人保护。

If you read this correctly it does mean that both algorithms may actually point to the same implementation. 如果你正确地阅读它,那确实意味着两种算法实际上可能指向相同的实现。


All in all, the fact that you don't see much of a difference (just random data) is the expected result. 总而言之,您没有看到太多差异(只是随机数据)的事实是预期的结果。 You may see a difference if you run the full set of FIPS sets on the random number generator - it depends on the implementation. 如果在随机数生成器上运行完整的FIPS集,您可能会看到差异 - 这取决于实现。

EDIT: As the meaning and the seeding of ALG_PSEUDO_RANDOM is not clear, I would advice to use ALG_SECURE_RANDOM over ALG_PSEUDO_RANDOM to retrieve cryptographically secure random numbers. 编辑:由于ALG_PSEUDO_RANDOM的含义和种子不清楚,我建议使用ALG_SECURE_RANDOM不是ALG_PSEUDO_RANDOM来检索加密安全的随机数。

In general either of the algorithms is pre-seeded by randomness obtained from the security processor of the CPU. 通常,任一算法都是通过从CPU的安全处理器获得的随机性预先播种的。 This means you cannot use the algorithms to create the same result even if you do supply it the seed. 这意味着即使您提供种子,也无法使用算法创建相同的结果。 This is good since you don't know the actual algorithm. 这很好,因为你不知道实际的算法。 If you want to do this you may have to program a stream cipher, DRBG or KDF yourself. 如果您想这样做,您可能需要自己编写流密码,DRBG或KDF。

I cannot see the source of your class RandomData , but I'll assume that you're using a SecureRandom . 我看不到你的类RandomData的来源,但我会假设你使用的是SecureRandom SecureRamdom is always seeded randomly and the seed cannot be forced to take a value (otherwise it wouldn't be secure!). SecureRamdom总是随机播种,种子不能被强制取值(否则它将不安全!)。

The following is taken from the SecureRandom.setSeed() javadocs 以下内容取自SecureRandom.setSeed() javadocs

public void setSeed(byte[] seed) public void setSeed(byte [] seed)

Reseeds this random object. 重新种植这个随机对象。 The given seed supplements, rather than replaces , the existing seed. 给定的种子补充而不是替代现有的种子。 Thus, repeated calls are guaranteed never to reduce randomness. 因此,保证重复呼叫永远不会减少随机性。

If you want repeatable "randomness" you need to use a standard Random object. 如果您想要可重复的“随机性”,则需要使用标准的Random对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM