2014-10-18 1 views
3

Примечание: из-за того, что я являюсь новым членом здесь, в stackoverflow и ограничениях репутации ссылок, мне нужно будет опубликовать большой фрагментов кода здесь.Шифрование/дешифрование в Android с RSA

EDIT: С тех пор я опубликовал это обновление как моего устройства Genymotion, так и моих SDK, и до сих пор мне удалось получить расшифрованный байт-массив, но с кучей ведущих нулей. Для этого я не затронул ни одну строку кода. Что-то определенно кажется странным с окружающей средой, на которой я запускаю приложение.

Я пытаюсь зашифровать и дешифровать случайно сгенерированный ключ AES (вместе с его IV), используя RSA, который затем я использую при шифровании данных, передаваемых между сервером и устройством Android. Я тестировал свой код с помощью устройства Genymotion, и до сих пор я сталкивался с этими проблемами.

Код был протестирован и ранее работал над настройкой рабочего стола, и проблема возникла только при копировании моего проекта Android в Android Studio. Я использовал эти методы шифрования и дешифрования на рабочем столе без проблем.

Я думаю, что мне удалось локализовать проблему как в моем шифрования RSA с помощью шифрования текста, а не получать одни и те же байт после расшифровки, хотя я не могу полностью исключить дополнительные ошибки:

private byte[] decrypt(byte[] bytes) throws Exception { 
    Cipher cipher = Cipher.getInstance("RSA/None/NoPadding"); 
    cipher.init(Cipher.DECRYPT_MODE, PRIVATE_KEY); 
    return cipher.doFinal(bytes); 
} 

private byte[] encrypt(byte[] bytes) throws Exception { 
    Cipher cipher = Cipher.getInstance("RSA/None/NoPadding"); 
    cipher.init(Cipher.ENCRYPT_MODE, SERVER_KEY); 
    return cipher.doFinal(bytes); 
} 

//Made this method to test my own keys, and whether or not encryption works 
private byte[] encryptMyOwnKey(byte[] bytes) throws Exception { 
    Cipher cipher = Cipher.getInstance("RSA/None/NoPadding"); 
    cipher.init(Cipher.ENCRYPT_MODE, PUBLIC_KEY); 
    return cipher.doFinal(bytes); 
} 

В конструктор, я только что добавил этот кусок кода, чтобы проверить эти два метода.

private ServerInterface(Context context) throws IOException { 
    //Some not so interesting code goes here 
    final KeyPair key = getKeyPair(context); 
    PRIVATE_KEY = (RSAPrivateKey) key.getPrivate(); 
    PUBLIC_KEY = (RSAPublicKey) key.getPublic(); 
    try { 
     //Some dummy text for testing 
     byte[] test = decrypt(encryptMyOwnKey("Decryption successful".getBytes())); 
     Log.i("ServerInterface", "Test result: "+new String(test)); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    //More code that isn't interesting 
} 

И методы, которые используются для получения KeyPair являются:

private static KeyPair getKeyPair(Context context) { 
    final File keyFileDirectory = new File(context.getFilesDir(), "rsa/"); 
    final File publicKeyFile = new File(keyFileDirectory, "sikkr_pub_key"); 
    final File privateKeyFile = new File(keyFileDirectory, "sikkr_priv_key"); 
    KeyPair key; 

    if (publicKeyFile.exists() && privateKeyFile.exists()) { 
     try { 
      key = getKeyPairFromFile(publicKeyFile, privateKeyFile); 
     } catch (Exception e) { 
      key = generateKeyPair(publicKeyFile, privateKeyFile); 
     } 
    } else { 
     key = generateKeyPair(publicKeyFile, privateKeyFile); 
    } 
    return key; 
} 

private static KeyPair getKeyPairFromFile(File publicKeyFile, File privateKeyFile) throws Exception { 
    Log.d("ServerInterface", "Getting the key pair from file"); 
    byte[] publicKey = readByteDataFromFile(publicKeyFile); 
    byte[] privateKey = readByteDataFromFile(privateKeyFile); 

    KeyFactory kf = KeyFactory.getInstance("RSA"); 
    RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new X509EncodedKeySpec(publicKey)); 
    RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(new PKCS8EncodedKeySpec(privateKey)); 
    return new KeyPair(pubKey, privKey); 
} 

private static KeyPair generateKeyPair(File publicKeyFile, File privateKeyFile) { 
    Log.d("ServerInterface", "Generating a key pair"); 
    KeyPairGenerator keyGen; 
    KeyPair key = null; 

    if (publicKeyFile.exists()) { 
     publicKeyFile.delete(); 
    } 

    if (privateKeyFile.exists()) { 
     privateKeyFile.delete(); 
    } 

    try { 
     keyGen = KeyPairGenerator.getInstance("RSA"); 
     keyGen.initialize(2048); 
     key = keyGen.genKeyPair(); 

     if (!publicKeyFile.getParentFile().exists()) { 
      publicKeyFile.getParentFile().mkdirs(); 
     } 

     publicKeyFile.createNewFile(); 
     privateKeyFile.createNewFile(); 
     saveByteDataToFile(publicKeyFile, key.getPublic().getEncoded()); 
     saveByteDataToFile(privateKeyFile, key.getPrivate().getEncoded()); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private static void saveByteDataToFile(File file, byte[] data) throws IOException { 
    DataOutputStream dos = new DataOutputStream(new FileOutputStream(file)); 
    dos.write(data); 
    dos.flush(); 
    dos.close(); 
} 

private static void readByteDataFromFile(File file) throws IOException { 
    DataInputStream dis = new DataInputStream(new FileInputStream(file)); 
    byte[] read = new byte[dis.available()]; 
    dis.readFully(read); 
    dis.close(); 
    return read; 
} 

бревен, которые я получаю от запуска приложения являются:

10-18 13:55:16.472 1251-1265/edu.chalmers.sikkr I/ServerInterface﹕ Setting up an interface to the server 
10-18 13:55:16.528 1251-1265/edu.chalmers.sikkr D/ServerInterface﹕ Generating a key pair 
10-18 13:55:17.004 1251-1265/edu.chalmers.sikkr I/ServerInterface﹕ Test result: JNk9���N+!N^9__ `D�)̊#O�K��\���Q�eD�(���M� 
&vK6���%M��,�9wg��!um7���t�9�w+�LGh�0ڼ{�s]���̅�����_͵b�͸-0��> ��[email protected]}��Wx|�g�_��P8;��t��:��5��8��o�͐w�Ơ����o$��2��jS2�Z��j̪����j�l_HZ�k���~�����7�b��N�fޒ�Ի*)I.IE� 

Как вы можете видеть, результат теста нигде не близок к расшифрованному тексту, что, скорее всего, вызвало проблемы для меня при тестировании всех функций. Я теряюсь относительно того, как это решить, поскольку большая часть кода ранее работала безупречно в среде рабочего стола. Помощь будет высоко оценена.

Edit: Новый выход я говорил ранее:

10-18 20:45:44.969 1301-1314/edu.chalmers.sikkr I/ServerInterface﹕ Test result: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Decryption successful 

Edit: Эта последняя проблема была также решена путем изменения в PKCS1Padding от NoPadding.

ответ

0

В функции generateKeyPair у вас есть:

saveByteDataToFile(privateKeyFile, key.getPublic().getEncoded()); 

, где оно должно было быть:

saveByteDataToFile(privateKeyFile, key.getPrivate().getEncoded()); 
+0

Мне очень жаль, что была опечатка, когда я скопировал текст с одного компьютера на другой. Исходный код так же, как вы сказали, это должно быть. Все равно дает мне тот же результат. Тем не менее, журналы не говорят, что читают из файла в этом экземпляре (потому что он запускается в первый раз), что означает, что он не должен искать в файле ключ. Я изменил свой первоначальный вопрос в соответствии с вашими исправлениями, чтобы избежать будущих путаниц. – Sweed

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

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