5

我正在尝试在 Android 上使用 Java 确定性地生成 RSA 密钥对。我的要求是我无法存储密钥对,并且必须在运行时生成它以等同于任何以前/未来的运行。

我的过程是,我将确定性地播种一个随机数生成器并传递该生成器以创建密钥。我的代码是:

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();

生成的密钥因运行而异。但是,SecureRandom 数字在每次运行时都是相同的,甚至在不同设备之间也是相同的。

我错过了什么?我怎样才能重复生成这些密钥?

谢谢

4

1 回答 1

9

你想做什么?即使这样可行,此代码也将依赖于 Android 上 SHA1PRNG 实现的一个怪癖,因此它可能随时中断。通常,setSeed()会增加熵,因此即使您SecureRandom使用相同的种子播种,也不能保证您将获得相同的数字。如果您在桌面 Java 上尝试此代码,它很可能会失败。到目前为止,它适用于大多数(所有?)当前的 Android 版本,但这不能保证。

如果您需要可预测的密钥,您可能需要为每个设备预置预生成的密钥。如果您需要安全地存储它们,请在 ICS 上使用KeyChainAPI,或在 ICS 之前的设备上使用受密码保护的密钥库。即使您不存储实际密钥,如果有人知道密钥是如何生成的(种子),他们也可以生成相同的密钥,并且您的密钥与种子一样安全。如果它是特定于设备的,那么可能并不难找到。

至于为什么这不起作用,RSA密钥生成器基本上BigIntegers在循环中生成随机数,测试素数。素数测试是概率性的,因此您可能会在每次运行时选择不同的素数。您可能想要获取SpongyCastle,在模拟器上运行它并设置断点RSAKeyPairGenerator.java以检查到底发生了什么。

于 2012-04-16T06:01:58.447 回答