生成的 RSA Public 和私钥模数在 Java/Android 中相同

Generated RSA Public and Private key modulus are the same in Java/Android

我是密码学的新手,我可能问了一个愚蠢的问题,但我一直找不到答案。我正在 POC Android 项目的 Java 中生成 RSA 密钥。我的目的是使用 public 密钥加密用户密码并使用服务器中的私钥对其进行解密,同时应用此方法将允许我以更安全的方式(加密)将密码保存在设备中,然后使用指纹身份验证时自动使用它。我正在使用常规 Java 方法生成密钥:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair key = keyGen.generateKeyPair();
PublicKey publicKey = key.getPublic();
PrivateKey privateKey = key.getPrivate();

然后我将两个密钥都记录到 Android Studio Logcat 这样:

Log.e(TAG, "Public key: " + publicKey);
Log.e(TAG, "Private key: " + privateKey);

...这就是我记录的内容:

10-18 15:27:17.570 22426-22426/cliu.tutorialcrypto E/AsymmetricAlgorithmRSA: Public key: OpenSSLRSAPublicKey{modulus=c1312eb5c24da9577dd40263cec233b8be40ed227b81df3c442363f1dfd5364e9e2ba96d4dd7c1011d2633d6603beb1a483b75b8af8a87b10ebe918729b6afe95893d5c93b3f99727785110f2373d20ced8bfe2421c9c682ee737c60a7c6199be3d2e7e4687d69cedc50965b8cebc4445cdfe7a13a7df5eda6a6d4304d057505,publicExponent=10001}
10-18 15:27:17.570 22426-22426/cliu.tutorialcrypto E/AsymmetricAlgorithmRSA: Private key: OpenSSLRSAPrivateCrtKey{modulus=c1312eb5c24da9577dd40263cec233b8be40ed227b81df3c442363f1dfd5364e9e2ba96d4dd7c1011d2633d6603beb1a483b75b8af8a87b10ebe918729b6afe95893d5c93b3f99727785110f2373d20ced8bfe2421c9c682ee737c60a7c6199be3d2e7e4687d69cedc50965b8cebc4445cdfe7a13a7df5eda6a6d4304d057505,publicExponent=10001}

问题:为什么生成的密钥中的两个模数相等?我认为这不够安全,因为只要有 public 密钥模数,就可以很容易地得出私钥,对吧?

您生成的是 Java 的密钥。密钥对的public和私钥总是共享相同的模数:计算在该域内执行。

保持安全的不是模数,而是私有指数和——通常也是可用的——使用中国剩余定理 (CRT) 执行快速求幂所需的参数。这些基本上是用于计算私钥和模数的质数P和Q等参数。

实际上,您可以使用模数来确定密钥 是唯一的,因为每个密钥对都应该具有唯一的模数。通过这种方式,您还可以检查 public 密钥和私钥是否属于同一对 - 无需进行签名生成/验证。


私有指数和CRT参数当然没有打印出来;模数足以识别私钥,您不会希望通过打印出来破坏私钥的安全性。

如果你想看到它们,那么 cast 你的私钥到 RSAPrivateCrtKey 并使用那个 class 的 getter。

请注意,只有基于软件的密钥才可能具有吸气剂 return 信息,因此请注意,尝试获取私有参数可能需要处理运行时异常。