2015-02-13 4 views
0

Я пишу приложение для Android, которое транслирует открытый ключ RSA в сеть и позволяет другим клиентам подключаться к нему через TCP. У меня есть собственный собственный протокол и структура пакетов, которые я затем шифрую и отправляю клиенту (пакет -> AES -> RSA с клиентом открытого ключа -> клиент).BadPaddingException при расшифровке RSA от другого клиента

private String encryptPacket(String packet, String pubKey) 
{ 
    PublicKey clientPub = KeyFunctions.stringToKey(pubKey); 
    String aesEncryptedData = null; 
    byte[] rsaEncryptedData = null; 
    String temp = null; 

    try 
    { 
     // AES 
     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
     final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, secretKey); 
     aesEncryptedData = Base64.encodeToString(cipher.doFinal(packet.getBytes()), Base64.NO_PADDING|Base64.NO_WRAP); //base64 the aes 

     // RSA 
     Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     c.init(Cipher.ENCRYPT_MODE, clientPub); 
     rsaEncryptedData = c.doFinal(aesEncryptedData.getBytes()); 
     temp = Base64.encodeToString(rsaEncryptedData, Base64.NO_PADDING|Base64.NO_WRAP); // base 64 the rsa 
     Log.d("ENC SEND", temp); 
    } catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
    return temp; 
} 

public String decryptPacket(String encryptedData, Context context) 
{ 
    // get the keys 
    PrivateKey pri = KeyFunctions.getPrivateKey(context); 
    byte[] packet = null; 
    byte[] decrypted = null; 
    String temp = null; 

    try 
    { 
     //RSA 
     Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     c.init(Cipher.DECRYPT_MODE, pri); 
     byte[] rsaTempArray = Base64.decode(encryptedData, Base64.NO_PADDING|Base64.NO_WRAP); 
     packet = c.doFinal(rsaTempArray); 

     // AES 
     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
     final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES"); 
     cipher.init(Cipher.DECRYPT_MODE, secretKey); 
     final String decryptedString = new String(cipher.doFinal(Base64.decode(packet, Base64.NO_PADDING|Base64.NO_WRAP))); 
     temp = decryptedString; 
    } catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
    Log.d("ENC REC", temp); 
    return temp; 
} 

Этот код работает, когда клиент отправляет данные себе. Тем не менее, он не работает при передаче его другому клиенту, что дает мне следующую ошибку: javax.crypto.BadPaddingException: error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02

Это исключение возникает при вызове decryptPacket, packet = c.doFinal(rsaTempArray);

Я попытался проверить, что значение общественности ключ является правильным с помощью отладки, и там, похоже, нет никаких проблем.

Update

Вот обновленный код

private byte[] encryptPacket(Packet packet, String pubKey) 
{ 
    PublicKey clientPub = KeyFunctions.stringToKey(pubKey); 
    byte[] aesEncryptedData = null; 
    byte[] rsaEncryptedData = null; 
    byte[] temp = null; 

    Log.d("START", "==========ENCRYPT=========="); 
    try 
    { 
     // AES 
     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
     final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, secretKey); 
     byte aesTempArray[] = cipher.doFinal(packet.getBytes()); 
     Log.d("ENC AES TEMP", new String(aesTempArray, "UTF-8")); 
     aesEncryptedData = Base64.encode(aesTempArray, Base64.NO_PADDING | Base64.NO_WRAP); //base64 the aes 
     Log.d("ENC AES ENCR", new String(aesEncryptedData, "UTF-8")); 

     // RSA 
     Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     c.init(Cipher.ENCRYPT_MODE, clientPub); 
     rsaEncryptedData = c.doFinal(aesEncryptedData); 
     Log.d("ENC RSA ENCR", new String(rsaEncryptedData, "UTF-8")); 
     temp = Base64.encode(rsaEncryptedData, Base64.NO_PADDING | Base64.NO_WRAP); // base 64 the rsa 
     Log.d("ENC RSA TEMP", new String(temp, "UTF-8")); 
    } catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
    return temp; 
} 

public Packet decryptPacket(byte[] encryptedData, Context context) 
{ 
    // get the keys 
    PrivateKey pri = KeyFunctions.getPrivateKey(context); 
    Packet p = null; 
    byte[] aesDecryptedData = null; 
    byte[] rsaDecryptedData = null; 


    Log.d("START", "==========DECRYPT=========="); 
    try 
    { 
     //RSA 
     Log.d("DEC INIT", new String(encryptedData, "UTF-8")); 
     Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     c.init(Cipher.DECRYPT_MODE, pri); 
     byte[] rsaTempArray = Base64.decode(encryptedData, Base64.NO_PADDING | Base64.NO_WRAP); 
     Log.d("DEC RSA TEMP", new String(rsaTempArray, "UTF-8")); 
     rsaDecryptedData = c.doFinal(rsaTempArray); 
     Log.d("DEC RSA ENCR", new String(rsaDecryptedData, "UTF-8")); 

     // AES 
     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
     final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES"); 
     cipher.init(Cipher.DECRYPT_MODE, secretKey); 
     byte[] aesTempArray = Base64.decode(rsaDecryptedData, Base64.NO_PADDING | Base64.NO_WRAP); 
     Log.d("DEC AES TEMP", new String(aesTempArray, "UTF-8")); 
     aesDecryptedData = cipher.doFinal(aesTempArray); 
     Log.d("DEC AES DEC", new String(aesDecryptedData, "UTF-8")); 
     p = new Packet(aesDecryptedData); 
    } catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
    return p; 
} 

код больше не использует какие-либо строки, но все приходит с тем же исключением. Теперь я убедился, что получатель получил те же самые данные, что и клиент. Программа отлично работает, когда клиент отправляет данные на сервер на том же устройстве, но я получаю исключение выше, когда пытаюсь отправить на другой сервер устройств. Оба устройства имеют свою собственную пару с открытым ключом/открытым ключом. Каждое устройство имеет открытый ключ друг друга.

+0

Я думаю, что вы можете найти ответ здесь http://stackoverflow.com/questions/24541112/decrypt-data-using-rsa-between-php-and-java-android-issue или здесь http: // stackoverflow .com/questions/24988787/throws-badpaddingexception-when-i-try-to-decrypt-the-encrypted-data-in-android –

+0

Использование 'String.getBytes()' очень распространенный и очень плохой способ передачи двоичных файлов данные вокруг. –

+0

Я обновил код для использования байтовых массивов вместо строк. По-прежнему имеет ту же проблему. – communistWatermelon

ответ

0

Код шифрования/дешифрования был в порядке, я использовал неправильный IP-адрес, чтобы выяснить открытый ключ. Спасибо за помощь, хотя!

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