Шифрование RSA: разница между Java и Android
Я использую RSA для шифрования имени пользователя и пароля на Android и расшифровки их на сервере (tomcat 6, java 1.6).
Android Encryption:
PublicKey pubKey = readPublicKeyFromFile(mod, ex);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherData = cipher.doFinal(data);
return cipherData;
Расширение Java Tomcat:
PrivateKey pubKey = readPrivateKeyFromFile(mod, ex);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pubKey);
byte[] cipherData = cipher.doFinal(data);
return cipherData;
Если я использую android part OUTSIDE android (только в основном методе), он отлично работает. Но не внутри моего андроида (Эмулятор). На стороне сервера я получаю следующую ошибку:
javax.crypto.BadPaddingException: Blocktype mismatch: 0
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:311)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:255)
at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
Я сохраняю mod и ex как константы BigIntegers, поэтому я не записываю их в файл.
Я знаю, что есть разница между java1.6 и java 1.5, поэтому оба скомпилированы с java 1.6.
Некоторая информация об отладке:
Во время отладки в android я вижу, что pubKey содержит модуль и показатель степени в шестнадцатеричном формате. И если я отлаживаю основной метод (опять тот же код), я вижу, что pubKey содержит модуль и показатель степени в десятичной форме.
Что я делаю неправильно?
Спасибо
Ответы
Ответ 1
Im делает RSA Encrypt в Android 2.2+ и расшифровывает на сервере tomcat 6 java 1.6.
Я получал эту точную проблему, читая повсюду и частично благодаря ответу @Femi, я наткнулся на то, что мне нужно.
Решение заключалось в том, чтобы использовать следующую спецификацию алгоритма для Cipher:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
Это работает с шифрованием как на смартфонах Android, так и на BlackBerry. Я знаю, что прошло четыре месяца с тех пор, как был задан вопрос, но на всякий случай кто-то другой справляется с этой проблемой.
Ответ 2
Я предлагаю вам использовать определенную инициализацию шифрования: в качестве примера
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
будет работать на обоих. Исключение, которое вы получаете (исключение BadPaddingException), происходит потому, что стандартное заполнение инициализации по умолчанию отличается от JVM для ПК и Android JVM.
Ответ 3
Во-первых, похоже, что вы инициализируете оба шифра открытым ключом. Шифрование использует открытый ключ, дешифрование использует закрытый ключ. Я надеюсь, что это просто опечатка.
У меня было много проблем с RSA-шифрованием, многое было проб и ошибок. Я предлагаю вам попробовать другого провайдера. Мне удалось реализовать RSA с помощью BouncyCastle.
Cipher wrapper = Cipher.getInstance("RSA", "BC");
wrapper.init(Cipher.ENCRYPT_MODE, publicKey);
encryptedData= wrapper.doFinal(unencryptedData);
Хотя, я создал свою собственную пару ключей, поскольку это было сеансовое шифрование.
kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();
publicKey = kp.getPublic();
privateKey = kp.getPrivate();