Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deterministic generation of RSA encryption key pairs

Tags:

java

android

rsa

I am trying to deterministically generate an RSA key pair using Java on Android. My requirements are such that I can't store the key pair and it must be generated at run time to be equivalent to any previous/future runs.

My though process was that I would deterministically seed a random number generator and pass that generator along to create the keys. My code is:

SecureRandom random=SecureRandom.getInstance("SHA1PRNG");
random.setSeed(1234);   //something device specific will be used to set this
KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024, random);

KeyPair pair=keyGen.generateKeyPair();
PublicKey pub=pair.getPublic();
PrivateKey priv=pair.getPrivate();

The resulting keys are different from run to run. However, the SecureRandom numbers are the same from run to run and even the same across devices.

What am I missing? How can I can I repeatably generate these keys?

Thanks

like image 820
Aaron Avatar asked Apr 16 '12 01:04

Aaron


1 Answers

What are you trying to do? Even if this works, this code would rely on a quirk of the SHA1PRNG implementation on Android, so it might break at any time. Generally, setSeed() adds entropy so you can't guarantee that you will get the same numbers even if you seed the SecureRandom with the same seed. If you try this code on desktop Java it will most probably fail. So far it works on most (all?) current Android versions, but this is not guaranteed.

If you want predictable keys, you might need to provision each device with pre-generated keys. If you need to store them securely, use the KeyChain API on ICS, or a pass-phrase protected keystore on pre-ICS devices. Even if you don't store the actual key, if someone knows how the keys are generated (the seed), they could generate the same keys, and your keys are only as secure as the seed. If it is device specific, chances are it's not too hard to find.

As for why this doesn't work, the RSA key generator basically generates random BigIntegers in a loop, testing for primes. The prime test is probabilistic, so you might get different primes chosen on each run. You might want to get SpongyCastle, run this on an emulator and set breakpoints in RSAKeyPairGenerator.java to check what exactly is going on.

like image 54
Nikolay Elenkov Avatar answered Sep 18 '22 14:09

Nikolay Elenkov