Я использовал BouncyCastleProvider (версия 1.54) для генерации пары ключей RSA, и я хочу проверить, действительно ли ключ. Согласно википедии ключ алгоритма RSA, как показано ниже:RSA KeyPairGenerator с BouncyCastleProvider e * d (φ (n)), не равным одному
- Выберите два различных простых чисел р и д
- Compute п = рд
- вычислить ф (п) = φ (р) φ (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.54version? И в чем проблема, если 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);
}
, если e * d (φ (n)) не равно единице, которую вы не можете расшифровать с помощью частного экспонента. Таким образом, это означает серьезную проблему с сгенерированным ключом. Может быть, только извлечение ключевых параметров имеет проблему (обычно это не требуется), и она работает для циклов шифрования/дешифрования? – Henry
@Henry Он отлично работает, и фактически я обнаружил, что φ (n) может равняться LCM (q-1, p-1), что будет меньше, чем φ (p) φ (q), а новая версия использования BC λ (n) = lcm (p-1, q-1) λ (n) = lcm (p-1, q-1) вместо φ (n). – Jaycee
Итак, вам нужно (a^e)^d == a (mod pq) и e * d == 1 (mod (p-1) * (q-1)), является достаточным условием для этого, но на самом деле, если e * d == 1 (mod λ (n)), это также работает. – Henry