Я использовал BouncyCastleProvider (версия 1.54) для создания пары ключей RSA и хочу проверить, действителен ли ключ. Согласно википедии, ключ алгоритма RSA выглядит следующим образом:
- Выберите два различных простых числа p и q
- Вычислить n = pq
- Вычислить φ(n) = φ(p)φ(q) = (p − 1)(q − 1) = n − (p + q − 1)
- Выберите целое число e такое, что 1 ‹ e ‹ φ(n) и gcd(e, φ(n)) = 1; т. е. e и φ(n) взаимно просты
- Определить d как d ≡ e−1 (mod φ(n)); это более четко сформулировано как: решить для d при заданном d⋅e ≡ 1 (mod φ(n))
Затем я генерирую 1000 пар ключей, из которых я обнаружил, что только около 30% пар ключей соответствуют d⋅e ≡ 1 (mod φ(n)). Однако я получил 100% d⋅e ≡ 1 (mod φ(n)), когда я не использую поставщика BC. Что-то не так с версией BC 1.54? А в чем проблема, если e*d(φ(n)) не равно единице. Кто-нибудь может помочь? Большое спасибо. и мой тестовый код Java, как показано ниже:
public void testRSAKey() throws NoSuchAlgorithmException {
KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider());
rsa.initialize(1024,new SecureRandom());
int total=0;
int isOne=0,notOne=0;
BigInteger one= new BigInteger("1");
while (total<1000) {
KeyPair keyPair = rsa.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
BCRSAPrivateCrtKey privateCrtKey = (BCRSAPrivateCrtKey) privateKey;
BigInteger primeP = privateCrtKey.getPrimeP();
BigInteger primeQ = privateCrtKey.getPrimeQ();
BigInteger p1 = primeP.add(new BigInteger("-1"));
BigInteger q1 = primeQ.add(new BigInteger("-1"));
BigInteger fn = p1.multiply(q1);
BigInteger publicExponent = privateCrtKey.getPublicExponent();
BigInteger privateExponent = privateCrtKey.getPrivateExponent();
BigInteger mod = publicExponent.multiply(privateExponent).mod(fn);//mod ought to be one
if(mod.equals(one)) {
System.out.println("e*d(mod fn)=" + mod);
isOne++;
}else {
System.out.println("e*d(mod fn) not equal to one");
notOne++;
}
total++;
}
System.out.println("total=" + total);
System.out.println("isOne=" + isOne);
System.out.println("notOne=" + notOne);
}