简体   繁体   中英

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. I used the apdu buffer as the seed :

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 . 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 :

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. 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. 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. This is however not made explicit in the API up to 3.0.4.

However, if you read the text of the constant ALG_PSEUDO_RANDOM you'll get:

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.


In general the distinction of ALG_PSEUDO_RANDOM and ALG_SECURE_RANDOM is not that clear. 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 .

The same goes for 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.

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.

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.

In general either of the algorithms is pre-seeded by randomness obtained from the security processor of the 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.

I cannot see the source of your class RandomData , but I'll assume that you're using a SecureRandom . SecureRamdom is always seeded randomly and the seed cannot be forced to take a value (otherwise it wouldn't be secure!).

The following is taken from the SecureRandom.setSeed() javadocs

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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