Reputation: 697
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?
Upvotes: 3
Views: 935
Reputation: 93948
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.
Upvotes: 5
Reputation: 29827
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.
Upvotes: 0