2017-01-11 3 views
2

В настоящее время я выполняю шифрование RSA на Java, и для шифрования я должен использовать частный и открытый модуль. Я в настоящее время имею следующий:RSA Шифрование с использованием модуля и экспоненты в Java

private void createPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException { 
     String publicModulus = "d2c34017ef94f8ab6696dae66e3c0d1ad186bbd9ce4461b68d7cd017c15bda174045bfef36fbf048" + 
       "73cfd6d09e3806af3949f99c3e09d6d3c37f6398d8c63f9a3e39b78a187809822e8bcf912f4c44a8" + 
       "92fe6a65a477ddea9582738317317286a2610ba30b6b090c3b8c61ffb64207229b3f01afe928a960" + 
       "c5a44c24b26f5f91"; 

     BigInteger keyInt = new BigInteger(publicModulus, 16); 
     BigInteger exponentInt = new BigInteger("10001", 16); 
     RSAPublicKeySpec keySpeck = new RSAPublicKeySpec(keyInt, exponentInt); 
     KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
     publicKey = keyFactory.generatePublic(keySpeck); 

    } 

private void createPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException { 
     String privateModulus = "6c97ab6369cf00dd174bacd7c37e6f661d04e5af10670d4d88d30148ec188e63227b8dac0c517cf9" + 
       "67aa73cd23684c9165dc269f091bfab33b6c5c7db95b54130e348255c30aaaac1c7f09ef701e0d6f" + 
       "6dc142d2e4ed78466cc104e28d50be7adf3863afc021dbdd8b5f0b968b7cd965242c7d8d4b32ee84" + 
       "0fac3cad134344c1"; 
     BigInteger privateModulusInt = new BigInteger(privateModulus, 16); 
     BigInteger exponentInt = new BigInteger("10001", 16); 
     RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(privateModulusInt, exponentInt); 
     KeyFactory factory = KeyFactory.getInstance("RSA"); 
     privateKey = factory.generatePrivate(privateKeySpec); 
    } 

В основном методе, который я следующее:

 createPrivateKey(); 
     createPublicKey(); 

     String data = "12"; 

     Cipher cipher1 = Cipher.getInstance("RSA/ECB/NoPadding"); 
     cipher1.init(Cipher.ENCRYPT_MODE, publicKey); 
     byte[] encryptedData = cipher1.doFinal(data.getBytes()); 

     Cipher cipher2 = Cipher.getInstance("RSA/ECB/NoPadding"); 
     cipher2.init(Cipher.DECRYPT_MODE,privateKey); 
     byte[] decryptedData = cipher2.doFinal(encryptedData); 
     System.out.println(new String(decryptedData)); 

В консоли я получаю следующее: .7p;% кВ 9yxaɼ {и не "12" Если я делаю String data = "12345";, я тогда получаю: javax.crypto.BadPaddingException: Message is larger than modulus

Во-первых, почему шифрование и дешифрование не работает? Почему я не возвращаюсь "12". Во-вторых, почему у меня не может быть данных более двух символов?

Примечание. Для получения значений модуля и экспоненты я использую следующее website.

ответ

1

Ошибка при создании секретного ключа. Вы обеспечиваете общественный показатель вместо частного и (как комментировали @ dave_thomsom_085) частный показатель вместо модуля

Изменения createPrivateKey() с

private static PrivateKey createPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException { 
     String publicModulus = "d2c34017ef94f8ab6696dae66e3c0d1ad186bbd9ce4461b68d7cd017c15bda174045bfef36fbf048" + 
       "73cfd6d09e3806af3949f99c3e09d6d3c37f6398d8c63f9a3e39b78a187809822e8bcf912f4c44a8" + 
       "92fe6a65a477ddea9582738317317286a2610ba30b6b090c3b8c61ffb64207229b3f01afe928a960" + 
       "c5a44c24b26f5f91"; 
     String privateExponent = "6c97ab6369cf00dd174bacd7c37e6f661d04e5af10670d4d88d30148ec188e63227b8dac0c517cf9" + 
       "67aa73cd23684c9165dc269f091bfab33b6c5c7db95b54130e348255c30aaaac1c7f09ef701e0d6f" + 
       "6dc142d2e4ed78466cc104e28d50be7adf3863afc021dbdd8b5f0b968b7cd965242c7d8d4b32ee84" + 
       "0fac3cad134344c1"; 
     BigInteger privateExponenInt = new BigInteger(privateExponent, 16); 
     BigInteger keyInt = new BigInteger(publicModulus, 16); 
     RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(keyInt, privateExponenInt); 
     KeyFactory factory = KeyFactory.getInstance("RSA"); 
     return factory.generatePrivate(privateKeySpec); 
    } 

Кроме того, вы не должны использовать сырые RSA без дополнения по соображениям безопасности. Используйте RSA/ECB/PKCS1Padding или новый OAEP отступы RSA/ECB/OAEPWithSHA1AndMGF1Padding

По this answer вы можете зашифровать с PKCS1Padding данных до 11 байт меньше, чем размер ключа. and using OAEP он должен быть меньше, чем размер ключа модуля - 41

Затем, используя ваши 1024 бит ключа:

  • PKCS1: (1024 bits/8) - 11 = 117 bytes
  • OAEP: (1024 bits/8) - 42 = 86 bytes

Также рекомендуется для использования CRT вместо частного экспонента напрямую

RSAPrivateCrtKeySpec privateKeySpec = 
    new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, primeP, primeQ, primeExpP, primeExpQ, crtCoefficient); 
+0

public exponent вместо частного _AND_ частного экспонента вместо модуля. В RSA нет такого общественного модуля или частного модуля в RSA; существует один модуль с государственными и частными показателями. И использование частного экспонента напрямую, а не CRT, истекает около 30 лет. И этот сайт ошибается в своей исторической заметке. Короче говоря, не полагайтесь на это. –

+0

Точная диагностика @ dave_thompson_085, я добавил ваши рекомендации. благодаря – pedrofb

 Смежные вопросы

  • Нет связанных вопросов^_^