我是密码学的新手,可能我在问一个愚蠢的问题,但我一直无法找到答案。我正在POC Android项目中用Java生成RSA密钥。我的目的是使用公共密钥对用户密码进行加密,然后使用服务器中的私钥对用户密码进行解密,同时应用该密码,将使我以更安全的方式(加密)将密码保存在设备中,然后在使用时自动使用使用指纹认证。我使用常规的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}
问题:为什么生成的密钥中的两个模数相等?我认为这是不够安全的,因为只有有人可以轻易拿出公钥模数,对吧?
最佳答案
您生成的是Java的密钥对。密钥对的公钥和私钥始终共享相同的模数:在该域内执行计算。
保持安全的不是模数,而是私有指数,以及-通常也可以使用-使用中国剩余定理(CRT)执行快速求幂所需的参数。这些基本上是用于计算私钥和模数的参数,例如素数P和Q。
实际上,您可以使用模数来确定密钥对是唯一的,因为每个密钥对都应具有唯一的模数。这样,您还可以检查公钥和私钥是否在同一对中,而无需进行签名生成/验证。
当然不打印私有指数和CRT参数。模数足以识别私钥,并且您不希望通过将其打印出来来破坏私钥的安全性。
如果仍然希望看到它们,则将私钥转换为RSAPrivateCrtKey并使用该类的getter。
请注意,只有基于软件的键才可能具有getter返回信息,因此请注意,尝试获取私有参数可能需要处理运行时异常。