Я знаю, что с https-соединением это может быть проще, но для университетского проекта для этого нет денег. У нас есть веб-сервер Apache2, но они не могут включать сертификат из-за ограничений на доступ. URL-соединение с отправкой данных является правильным, поэтому я не включил его в свой вопрос, поэтому проблема связана с форматированием или de-/encryption.
Итак, базовая идея: создать собственный сертификат с openssl. Шифруйте данные на Android, отправляйте с сервером UrlConnection на сервер, там он должен быть расшифрован, чтобы выполнять больше операций.
Android Encryption:
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");
Параметры строковой кодировки будут отправляться с данными 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, но строка дешифрования пуста. Если я шифрую String в php, я могу его расшифровать, то же самое на Android, я думаю, проблема связана с форматированием HTTP-запроса с UTF-8 Urlencoding или так, но я не получаю для этого решения. Пожалуйста, помогите мне решить эту конкретную проблему.
Хорошо, я получил это, работая с Java, но не на Android: Java Code:
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;
Любая идея, что я делаю неправильно?
С обновленным кодом я помещаю неправильный сертификат в приложение. Теперь он работает.
Base64
затем после этого вы кодировали вutf-8
почему это так?