I know it could be easier with https connection, but for the university project there is no money for that. We have an Apache2 Webserver, but are not able to include a certificate due to permission restrictions. URL Connection with sending the data is correct so I did not include it to my question, so the problem is with formatting or de-/encryption.
So the base Idea is: Generate a own Certificate with openssl. Encrypt the Data on Android, send with UrlConnection to the server, there it has to be decrypted to perform more operations.
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");
The String parametersencrypted will be send with POST Data to the Server Now the Server Part: PHP Decryption:
$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);
The Server is getting the Base64 Encoded String, but the decryption String is empty. If I encrypt a String in php I am able to decrypt it, same on Android, I think the problem is with the formatting for HTTP Request with UTF-8 Urlencoding or so, but I am not getting a solution for it. Please help me to solve this specific problem.
UPDATE
Ok I did got it working with Java, but not on 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("/", "_");
Modified PHP:
$data = base64_decode(strtr($string, '-_', '+/'));
openssl_private_decrypt($data, $decrypted, $this->privateKey,OPENSSL_NO_PADDING);
Android Code:
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;
Any idea what I am doing wrong?