Я знаю, что это может быть проще с https, но для университетского проекта денег на это нет. У нас есть веб-сервер Apache2, но мы не можем включить сертификат из-за ограничений разрешений. URL Соединение с отправкой данных правильное, поэтому я не включил его в свой вопрос, поэтому проблема с форматированием или дешифрованием / шифрованием.
Итак, основная идея заключается в следующем: создать собственный сертификат с помощью openssl. Зашифруйте данные на Android, отправьте с помощью UrlConnection на сервер, там его необходимо расшифровать, чтобы выполнить больше операций.
Шифрование Android:
AssetManager assetManager=activity.getAssets();
InputStream in=assetManager.open("certificate.crt");
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)certificateFactory.generateCertificate(in);
PublicKey publicServerKey = certificate.getPublicKey();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,publicServerKey);
byte[] parametersCipher = cipher.doFinal(parameters.getBytes());
String encoded=new String(Base64.encode(parametersCipher, Base64.DEFAULT));
String parametersencrypted="data="+URLEncoder.encode(encoded,"UTF-8");
String параметрsencrypted будет отправлен с POST-данными на сервер
Теперь серверная часть:
Расшифровка PHP:
$data=utf8_decode(urldecode($_POST['data']));
$privateKey=openssl_pkey_get_private("file://certificate.key", "password");
$data = base64_decode($data);
openssl_private_decrypt($data, $decrypted,$privateKey);
Сервер получает закодированную строку Base64, но строка расшифровки пуста. Если я зашифрую строку в php, я смогу расшифровать ее, то же самое на Android, я думаю, что проблема заключается в форматировании HTTP-запроса с кодировкой UTF-8 или около того, но я не получаю решения для этого.
Пожалуйста, помогите мне решить эту конкретную проблему.
Хорошо, я работал с Java, но не с Android:
Java-код:
Cipher cipher=Cipher.getInstance("RSA/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,publicServerKey);
byte[] parametersCipher = cipher.doFinal(urlParameters.getBytes("UTF-8"));
String encoded=new String(encoder.encode(parametersCipher)); //encoder= base64 encoder
encoded=encoded.replace("+", "-");
encoded=encoded.replace("/", "_");
Модифицированный PHP:
$data = base64_decode(strtr($string, '-_', '+/'));
openssl_private_decrypt($data, $decrypted, $this->privateKey,OPENSSL_NO_PADDING);
Код Android:
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,publicServerKey);
byte[] parametersCipher = cipher.doFinal(parameters.getBytes("UTF-8"));
String encoded=new String(Base64.encode(parametersCipher, Base64.URL_SAFE)); //URL_SAFE from Android Documentation + as - and / as _
String parametersencrypted="data="+encoded;
Есть идеи, что я делаю не так?
С обновленным кодом я приложил неверный сертификат к приложению. Теперь это работает.
Других решений пока нет …