2013-03-23 2 views
1

Я разрабатываю приложение для Android. К сожалению, у меня проблема совместимости. Мой исходный код работает с прошивкой 4.1, но сбой с устройствами с прошивкой 2.2. Ошибка, похоже, является «ClassNotFoundException», вызванной ObjectInputStream.Ошибка RSA-шифрования/дешифрования на Android 2.2

Мой исходный код для шифрования и дешифрования:

private Key getPublicKey() { 
    try { 
     InputStream fis = activity.getResources().openRawResource(R.raw.publick); 
     ObjectInputStream ois = new ObjectInputStream(fis); 
     Key RSApublicKey = (Key) ois.readObject(); 
     return RSApublicKey; 
    } 
    catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 
    catch (IOException e) { 
     e.printStackTrace(); 
    } 
    catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

private Key getPrivateKey() { 
    try { 
     InputStream fis = activity.getResources().openRawResource(R.raw.privatek); 
     ObjectInputStream ois = new ObjectInputStream(fis); 
     Key RSAprivateKey = (Key) ois.readObject(); 
     return RSAprivateKey; 
    } 
    catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 
    catch (IOException e) { 
     e.printStackTrace(); 
    } 
    catch (ClassNotFoundException e) { 
     Log.e("error", "Error: " + e); 
     e.printStackTrace(); 
    } 
    return null; 
} 

public byte[] encrypt(String data) { 
    byte[] encrypted = null; 
    try { 
     Cipher cipher = Cipher.getInstance("RSA"); 
     cipher.init(Cipher.ENCRYPT_MODE, getPublicKey()); 
     encrypted = cipher.doFinal(data.getBytes()); 
    } 
    catch (IllegalBlockSizeException e) { 
      e.printStackTrace(); 
    } 
    catch (BadPaddingException e) { 
     e.printStackTrace(); 
    } 
    catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } 
    catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } 
    catch (NoSuchProviderException e) { 
     e.printStackTrace(); 
    } 
    return encrypted; 
} 

public String decrypt(byte[] encrypted) { 
    byte[] decrypted = null; 
    try { 
     Cipher cipher; 
     cipher = Cipher.getInstance("RSA"); 
     cipher.init(Cipher.DECRYPT_MODE, getPrivateKey()); 
     decrypted = cipher.doFinal(encrypted); 
    } 
    catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } 
    catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } 
    catch (IllegalBlockSizeException e) { 
     e.printStackTrace(); 
    } 
    catch (BadPaddingException e) { 
     e.printStackTrace(); 
    } 
    catch (NoSuchProviderException e) { 
     e.printStackTrace(); 
    } 
    return new String(decrypted); 
} 

Ошибка в LogCat:

03-23 10:13:19.706: E/Error(427): Error: java.lang.ClassNotFoundException: com.android.org.bouncycastle.jce.provider.JCERSAPrivateCrtKey 

У вас есть какие-либо идеи, как я мог заставить его работать с андроид 2.2?

+0

[Вы уже задали этот вопрос] (http://stackoverflow.com/questions/15501592/problems-outsourcing-rsa-encryption-and-decryption). Вы должны отредактировать исходный вопрос, а не публиковать новый вопрос. –

+0

@ DuncanJones Хм, этот вопрос оставляет много информации, и, поскольку у нее нет ответов, вероятно, лучше сделать обратное. Я согласен с тем, что один из них, вероятно, должен идти, если только это не разные проблемы (но я не думаю, что они есть). –

ответ

0

Вы можете использовать метод Key.getEncoded() для сериализации ключа. Key.getFormat() уже намекает, что закрытые ключи RSA должны по умолчанию использовать кодировку PKCS # 8.

Вы можете использовать класс PKCS8EncodedKeySpec и экземпляр "RSA"KeyFactory, чтобы десериализовать полученный массив байтов.

Сериализованные ключи могут работать некорректно в разных реализациях PrivateKey (как вы уже выяснили к настоящему времени), а PKCS # 8 - это четко определенный и часто используемый стандарт.

+0

С моего мобильного телефона я изменю ответ сегодня вечером. –

+0

Можете ли вы рассказать мне, как это работает? Я знаю только свой метод. Или проще написать собственные классы для шифрования RSA? Звучит интересно. – JavaForAndroid

+0

Простой поиск 'PKCS8EncodedKeySpec' должен быть достаточным, например. http://stackoverflow.com/questions/7216969/getting-rsa-private-key-from-pem-base64-encoded-private-key-file использует этот метод для создания закрытого ключа. обратно из массива закодированных байтов. Таким образом, вы сериализуете/десериализуете массив байтов вместо самого класса. –

0

Ну, если он работает на 4.1+, но не на 2.2, я предполагаю, что это класс от android, который был включен после 2.2. Вы можете проверить это, пытаясь скомпилировать с android 2.2 проект, который использует этот класс, и посмотреть, можете ли вы это сделать. Если это так, просто найдите его и включите в свой проект.

+0

Я уже изменил цель target = android-15 на target = android-8 в файле project.properties. Но я должен установить цель сборки 4.0, потому что я использую панель действий Шерлока. Изменение цели сборки показывает, что ошибка «R не может быть решена». Это происходит из-за ActionBar, который вызывает ошибки в файлах макета xml. – JavaForAndroid

+0

Итак, создайте новый проект Android с целевым 8 и попробуйте получить доступ к этому классу. – crios

+0

Я никогда не могу получить доступ к этому классу. Также не с целью сборки 15. – JavaForAndroid