I am using this (Android: decrypt RSA text using a Public key stored in a file) as a guideline to encrypt a "string" using a public key and then decrypting with private key in ruby.
However, I am having difficulty. Part of the reason is that I am encrypting the bytes in Java and then when I am decrypting in Ruby I am not translating it.
I am attaching the Android snippet below:
// reads the public key stored in a file
AssetManager am = mContext.getAssets();
InputStream is = am.open("public_key.pem");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = br.readLine()) != null)
lines.add(line);
// removes the first and last lines of the file (comments)
if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size()-1).startsWith("-----")) {
lines.remove(0);
lines.remove(lines.size()-1);
}
// concats the remaining lines to a single String
StringBuilder sb = new StringBuilder();
for (String aLine: lines)
sb.append(aLine);
String keyString = sb.toString();
// converts the String to a PublicKey instance
byte[] keyBytes = Base64.decode(keyString.getBytes("utf-8"), 0);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(spec);
//byte[] encryptedText = null;
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
String encryptedText = Base64.encodeToString(cipher.doFinal(message), 0);
return encryptedText;
I am using following code in ruby to try and decode the encrypted data
pkey = OpenSSL::PKey::RSA.new private_key
print pkey.private_decrypt(Base64.decode64(android_encrypted_value))
I noticed a problem right away when testing that the base64 values generated in Java doesnt match the ones I generated in another code in ruby.
Any idea?
The following change worked for me:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, key);
String encryptedText = Base64.encodeToString(cipher.doFinal(message), Base64.DEFAULT);
I was able to apply this to my Ruby code and make it work.
Related
I'm trying to decrypt a server response using AES (256/ECB) but getting a wrong result. When I try the same inputs with this online tool I get the right result but running my code is giving a wrong result. Here's my decryption code
//input is a Hex encoded String of the response
public String decryptString(String input){
SecretKeySpec keySpec = new SecretKeySpec(Hex.decodeHex(key),"AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE,keySpec);
byte[] output = cipher.doFinal(Hex.decodeHex(input));
String outputString = Base64.encodeBase64String(output);
return outputString;
}
The parameters I entered into the online tool are :
key = 57e17ae84ceb2938c1f464e902f004919ea08fa7de5e358d1df028fde98d456d
input = 1c6f645bed9019332e94b69bd0152015b41dfce6c7f83046a59e1f80bce302a1ea59ccd15adbd7fcd5e7579cdaea1178fa9540ff0afa74cfe85c4e3244f9255f6dc3808b76088203bf28af25191d9d79487a2f7fb3a53bf7ee50d735d748dd16fbc3f19f9ebcf33a44d95bb221ef47fb577450d207ce6c5b762dc70142c9b7c1d815137ce24bf34fd0f5d2e0ab618c9087ef62327657f1f6c31f164109a4d190973c998e02971e6438dfc1af8dffc28cad0aa9a91a62f57d15200934cd18935b93d7327f7f8a41498ac416d90316a963cc736ce5d4fcde8401ec2f83714c4b202ddb69ce5fde1b61d69caadc2c7a162d7e88f2c5c671832f0bc4f14c98a4e2b9c4c84666a60530623f17c2f960b60c4a7242e10752cb863d41153c451dfc7d5cc4e2e9a8f8c0641764c8fca05f7db2b6
Just wanted to share the answer in case anyone stumbles into the same problem.
The result was actually the right result, the missing part was encoding the resulting byte array as a string using UTF-8 charset. The function becomes
public String decryptString(String input){
SecretKeySpec keySpec = new SecretKeySpec(Hex.decodeHex(key),"AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE,keySpec);
byte[] output = cipher.doFinal(Hex.decodeHex(input));
String outputString = new String(output,"UTF-8");
return outputString;
}
I am getting an encrypted string from the backend server, which I need to decrypt using private key in Android.The decryption works, but it appends a special character at the end of the decrypted string.
Here is the code I am using:
public static String decryptString(String value, Context context){
value = "Ss7LVqgWeamgPGkt62qSNydTJnwiUet8UemYWR0jzCLOvtW+RazpJmGG657/nWhu5UQGXzEMwIK1jcBXIXkw3EAX6WdocYBKpVJPWpmlEbf4IzPcev67wgx4vd3ylK8KrpPDj92EKE6ElDi/U91e+VS3bhURHye0w9ncaITTm+szGFiDL/fcy+0hnrYJdA3IrElZntYk14SCccb2M0LJ+nTFdfzEgsUH8vW5ei986d4HTKUqBvkoU+JAtHXTYq1sKNSd4L3Xm5fZ0OPpdIKEWqHDntjsMRsX62eTON+iC1OVsKK2vRqvSbVLvE45ww3N6iZNBG1gewcC8v5wJwonmA==";
byte[] decodedBytes = null;
try {
//Cipher c = Cipher.getInstance("AES/ECB/PKCS7Padding", "AndroidOpenSSL");
//Cipher c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", "AndroidOpenSSL");
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
c.init(Cipher.DECRYPT_MODE, getPrivateKey(context) );
decodedBytes = c.doFinal(Base64.decode(value, Base64.DEFAULT));
//decodedBytes = c.doFinal(value.getBytes("ISO-8859-1"));
} catch (Exception e) {
e.printStackTrace();
}
return new String(decodedBytes);
}
public static PrivateKey getPrivateKey(Context context){
// reads the key_public key stored in a file
InputStream is = context.getResources().openRawResource(R.raw.key_private);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
List<String> lines = new ArrayList<String>();
String line = null;
try {
while ((line = br.readLine()) != null)
lines.add(line);
// removes the first and last lines of the file (comments)
if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size()-1).startsWith("-----")) {
lines.remove(0);
lines.remove(lines.size()-1);
}
// concats the remaining lines to a single String
StringBuilder sb = new StringBuilder();
for (String aLine: lines)
sb.append(aLine);
String keyString = sb.toString();
byte [] encoded = Base64.decode(keyString, Base64.DEFAULT);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey myPrivKey = keyFactory.generatePrivate(keySpec);
return myPrivKey;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
Finally, I call the first function from the main activity:
String decryptedString = AppUtils.decryptString(encryptedString, MainActivity.this);
I am attaching my private key for reference:
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDuDOP1sBXEKUwR
WQcH459iGj74fGPqnIFJ+cOxNFFeymXs0L0u4n7v6NCAGvZJ5HtdWeUbT+xMMNMW
k8swrQs/qZ36KXzxhL6hy0gj4i86G5L73vQ39g/qlnxhfR+OxhVnDUE4TOt9xhN9
20Mf6xVhVOVmUQwhny6sQqvkhaebzJ32QuTlHFVT8mMGSTwXcHUqRi2ApeyRW9ln
BCLf/P5k+/O5W4lRmyfvumZoipegf0e75hGmgJYxXETomU50DmLMNdQ05/rlpcW5
FEm3Gf60pd+/mqkB+3LlyTPAM7sEfwKgL+CZSqYtz3O/m7tYSK7BtCIbE1bvksjj
bPQA1DYXAgMBAAECggEAZDvDRLEnCRjGccuFvVmnw7v/ZcuimqfZfJeRQa0g0gPx
FNzzu6kc/9GM8VPo/kYZd74hTPXDLnWkfC4w8Ub7pIu7/Bi6Bkv5pNCeiJV1g0cX
BbzkIigWnZVNvBLeVdSsMF8RZi5lPelITcckJW1r7Da9/O4FaKbJFTlhfXCVmXCn
74Bs0q8QZHA/WLwcy5DP+uqdko8T3vtBSPx7HEBbEhy94SEAsQfkdLTa0KQ2WlLI
ythR5DH0GUIoTIBeFsM7w2Ldj7EYbviC8OlIu3h3wHwPutAVzweqsSq5OPAwPnNP
oQZz6gqNaldE0jwVDD8aoLOzCrw1+NW0AmzWJx1VgQKBgQD5g1m8PagCwb/2BQqi
Q3ORjmbHS9dIo3IV+2RM7bYag5fv5CEfApH42rGzPr/pebmYIVQnfYkqDrfHmR95
56+7bOXxKDTkSCdursRa23L3WbIokhLJOPVr7FARc+mKFUEkrpHZcDsIoIUw+Bn4
Sa2myhFvazuJoGpjjAk8olpc1wKBgQD0PT+/ahG5tWW9Nt7wvQfi+KWW5l0fWb+R
ozbuFnZbmKkQZ45bCdU/G3qImtdtTynGX4LjaSyh/vEtebLlrCsfzRc7hQRHpM3o
9tjPUX8zSFNQQA8I7+iTQRQtdiAeOeEt5kethWG9qSbnkBFzkXwVhdvdkhRy4EzW
aKVwU26IwQKBgQCa4oiPq45ht7fbliGVvF0/G7B9QnzvIFavgpAumNkT+GAWj/xn
bYcDfW4VoHwtCFzHLNk6clj0/JHkmw7I86NIqz7JxnWex5OCx4YoCFWDafCH8rUq
p+rhBZ5mVxe/mZYImTz8Rwi+QDatwTUNxV7ATGsqSNx6gFPKW6FYPEfvnQKBgEvd
fqCxjOH3k6urkKKMxRdejukJk2F6mkPdw+E+vvMCv3kmAZULv96DZZNrLYF5tos0
/c4vzDphm365r7Uhvp95MD8/uS2b5o33py72rKE8VQy3aTQoeUDMVT0t1RoudmCw
iBFBPjQQh9Ij8RfJ2BZDZyEzEAEC5TswdDso30vBAoGBAJQqlK6mjhyCmqAs8V2j
vHbzv2/NTG2sYOaMGMsk1Zeh5nQq98rHA/7s1eEkX4AlC38QXisvKi7ywYrlpZoz
+K0Z1sd0tlysH74cK8xWDnLQ4j9l0rD9RtxYHlrdldrsP4P4rE1a2SwAchM3GDpG
R3LcU9BOe9ch+aW3b+PRIkgK
-----END PRIVATE KEY-----
Here is the output:
NDcxMDQ3MjguMTQ2ODg3NTI4MTr4iAAldbBVX2RD3cNw/rlKpmOp1p8YXIYqUVlvX7rmgg==��
The decrypted string should end with "==".Can someone kindly help me to figure out, how to remove the special characters at the end of the decrypted string.
Thanks
These values at the end must have been added during encryption. They are probably 00 valued bytes that were added by a language with null terminated strings or similar. The point is that PKCS#1 unpadding will fail if the ciphertext itself is altered, so the only reasonable explanation is that the values have been included in the plaintext.
Print out the decodedBytes in hexadecimals to find out the values. You can likely get rid of them by using the String#trim() method.
I'm trying to implement the login logic in my android app.
This is the scenario:
on click the app send a GET Request to Azure Server and receive an XML string with the RSA Public Key (module + exp)
the password is hashed and encripted
RSA(hash(pwd)) is sent to my server.
I'm using this logic in my angular app and it working well.
The problem
When I'm trying to encrypt my hashed password the method retur some illeggible character.. A conversion problem?
The Android Code
if (jsonToken.has("data"))
{
// Converte la Stringa in XML
String publicToken = jsonToken.getString("data");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document publicTokenXML = builder.parse(new InputSource(new StringReader(publicToken)));
Log.i("out", token.toString());
Log.i("outXML", publicTokenXML.getFirstChild().getFirstChild().getNextSibling().getTextContent());
// prendo le due parti che mi servono dall'XML
byte[] expBytes = Base64.decode(publicTokenXML.getFirstChild().getFirstChild().getNextSibling().getTextContent(), Base64.NO_PADDING);
byte[] modBytes = Base64.decode(publicTokenXML.getFirstChild().getFirstChild().getTextContent(), Base64.NO_PADDING);
byte[] dBytes = Base64.decode(d, Base64.DEFAULT);
BigInteger modules = new BigInteger(1, modBytes);
BigInteger exponent = new BigInteger(1, expBytes);
BigInteger d = new BigInteger(1, dBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Cipher cipher = Cipher.getInstance("RSA");
RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(modules, exponent);
PublicKey pubKey = keyFactory.generatePublic(pubSpec);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted = cipher.doFinal(bin2hex(getHash(pwd)).getBytes("UTF-8"));
// new String(encrypted)) is correct?!?
Log.i("encrypted: ", new String(encrypted));
RSAPrivateKeySpec privSpec = new RSAPrivateKeySpec(modules, d);
PrivateKey privKey = keyFactory.generatePrivate(privSpec);
cipher.init(Cipher.DECRYPT_MODE, privKey);
byte[] decrypted = cipher.doFinal(encrypted);
System.out.println("decrypted: " + new String(decrypted));
Log.i("hash", bin2hex(getHash(pwd)));
}
'decrypted' and 'hash' logs return to me the same hash string. I logged the part of the public and private key and they are correct.
BUT
How I can read it in the right form?
Thanks everyone.
** EDIT/Solution **
For who, how me, followed some tutorial on the web for implement RSA encryption in .NET, this is the solution that worked for me for the scenario I described at the top of the SO Query:
The Android Code
if (jsonToken.has("data"))
{
// Converte la Stringa in XML
String publicToken = jsonToken.getString("data");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document publicTokenXML = builder.parse(new InputSource(new StringReader(publicToken)));
Log.i("out", token.toString());
Log.i("outXML", publicTokenXML.getFirstChild().getFirstChild().getNextSibling().getTextContent());
// <RSAKeyValue><Modulus>*Modulus*</Modulus><Exponent>*Exponent*</Exponent></RSAKeyValue>
byte[] expBytes = Base64.decode(publicTokenXML.getFirstChild().getFirstChild().getNextSibling().getTextContent(), Base64.DEFAULT);
byte[] modBytes = Base64.decode(publicTokenXML.getFirstChild().getFirstChild().getTextContent(), Base64.DEFAULT);
byte[] dBytes = Base64.decode(d, Base64.DEFAULT);
BigInteger modules = new BigInteger(1, modBytes);
BigInteger exponent = new BigInteger(1, expBytes);
BigInteger d = new BigInteger(1, dBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// *****
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// *****
RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(modules, exponent);
PublicKey pubKey = keyFactory.generatePublic(pubSpec);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted = cipher.doFinal(bin2hex(getHash(pwd)).getBytes("UTF-8"));
// *****
Log.i("encrypted: ", Base64.encodeToString(encrypted, Base64.DEFAULT).replace("\n", ""));
// *****
// Decrypt
RSAPrivateKeySpec privSpec = new RSAPrivateKeySpec(modules, d);
PrivateKey privKey = keyFactory.generatePrivate(privSpec);
cipher.init(Cipher.DECRYPT_MODE, privKey);
byte[] decrypted = cipher.doFinal(encrypted);
System.out.println("decrypted: " + new String(decrypted));
Log.i("hash", bin2hex(getHash(pwd)));
}
** The .NET Core code **
private string RsaMyAndroidDecrypt(string passwordCrypt)
{
// Don't use OAEP padding (PKCS#1 v2).
var doOaepPadding = false;
// ------------------------------------------------
// Decrypt
// ------------------------------------------------
// Convert base64 string back to bytes.
var encryptedBytes = Convert.FromBase64String(passwordCrypt);
// Create a new instance of RSACryptoServiceProvider.
var rsa = new RSACryptoServiceProvider();
// Import the RSA Key information.
rsa.ImportParameters(keyForUserPassword.ExportParameters(true));
// Decrypt byte array.
var decryptedBytes = rsa.Decrypt(encryptedBytes, doOaepPadding);
// Get decrypted data.
return Encoding.UTF8.GetString(decryptedBytes);
}
For .NET core you shouldn't use RSACryptoServiceProvider, but rather:
private byte[] Decrypt(string input)
{
// Don't use OAEP padding (PKCS#1 v2).
RSAEncryptionPadding padding = RSAEncryptionPadding.Pkcs1;
// ------------------------------------------------
// Decrypt
// ------------------------------------------------
// Convert base64 string back to bytes.
byte[] encryptedBytes = Convert.FromBase64String(passwordCrypt);
// Create a new instance of RSA.
using (RSA rsa = RSA.Create())
{
// Import the RSA Key information.
rsa.ImportParameters(keyForUserPassword.ExportParameters(true));
// Decrypt byte array.
byte[] decryptedBytes = rsa.Decrypt(encryptedBytes, padding);
return decryptedBytes;
}
}
I'm ignoring the part here where you're turning it into a UTF-8 string. And the part where you're recovering a thing that you call a password.
RSACryptoServiceProvider only works on Windows. RSA.Create() will return an appropriate implementation of RSA for whatever platform the code is executing on.
I need to use PublicKey to encrypt session key but I have public key as Base64 encoded string so I tried to convert it as :
KeyFactory kf = KeyFactory.getInstance("RSA"); // or "EC" or whatever
byte[] keyBytes = _publicKey.getBytes();
byte[] publicKeyBytes = Base64.decode(keyBytes, Base64.DEFAULT);
X509EncodedKeySpec publicKeySpecs = new X509EncodedKeySpec(publicKeyBytes);
Log.v("", "X509 KS" + publicKeySpecs);
publicKey = kf.generatePublic(publicKeySpecs);
But I am getting public key as null value and getting exception as :
java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
If anyone has idea how to do it or have working code then please help me.
Thanks in Advance
Hi guys I generated Public Key from Base64 encoded String .
after wondering for few days this code worked for me.
String _publicKey= base64encoded_publickey;
// InputStream fileInputStream = null;
try {
// Receiving side
byte[] decodedBytes = Base64.decode(_publicKey, Base64.DEFAULT);
fileInputStream = new ByteArrayInputStream(decodedBytes);
// Print the decoded string
String decodedString = new String(decodedBytes);
CertificateFactory certFactory = CertificateFactory
.getInstance(CERTIFICATE_TYPE);
// certFactory.
X509Certificate cert = (X509Certificate) certFactory
.generateCertificate(fileInputStream);
publicKey = cert.getPublicKey();
Log.d("TAG", "Public key of the certificate:" + publicKey);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Could not intialize encryption module",
e);
} finally {
if (keyStream != null) {
try {
keyStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hope it will help you...Thanks...
well, last time it worked for me (I used bouncyCastle library..), you might need to modify it if it doesn't suit your need..
KeyPairGenerator keyGen = null;
KeyPair kp = null;
keyGen = KeyPairGenerator.getInstance("ECDSA", "BC");
ECGenParameterSpec ecSpec = new ECGenParameterSpec("brainpoolp160r1");
keyGen.initialize(ecSpec, new SecureRandom());
kp = keyGen.generateKeyPair();
EDIT:
(oops my bad, that's for initial generation..)
at that time I stored them as one..
and I need to convert the Base64 string back to array of byte first, and split them into part 1 and part 2..
private void splitKeyPair (byte[] thekeypair, byte[] part1, byte[] part2)
{
System.arraycopy(thekeypair, 0, part1, 0, 68);
System.arraycopy(thekeypair, 68, part2, 0, 115);
}
byte[] part1 = new byte[68];
byte[] part2 = new byte[115];
splitKeyPair(inputBuffer, part1, part2);
fact = KeyFactory.getInstance("ECDSA", "BC");
kp = new KeyPair(fact.generatePublic(new X509EncodedKeySpec(part1)),
fact.generatePrivate(new PKCS8EncodedKeySpec(part2)));
hope it helps..
*note: the size might vary, depending on the spec..
I encrypt data in Android application and encode it to send over to php webservice.
Then I decode it and decrypt it using $rsa->decrypt(base64_decode($data));
$rsa->decrypt return false. Why is that so?
This is the code in android
//get private key
String privateKeyString = "MIICWwIBAAKBgQDVIJ8H3Oszc5fWdgpwymWksF1WxkXJHIfdS6Ta1bHeqwEzPIkN f3iVk14LfaoSZpRb9Yvi/jvkXxIzJbHq6aKfnQOC6tKIiixvVvpCfxr1eV4urDdz H9RNy9bqGdXzTQdgQi+KRx0Dcy9RNsl7ZGLAGrUFRnPI4GTdH+7wm4QogQIDAQAB AoGAcUcKX7KC7HDm5h0NRY+94H/AzItLsi3Q5MT81Tc5d+EqHSJysdLrs4yFMtRS 3b7Z4dqrxDVefe4uDTNe0j3lqboKz8oKwAU+paKx3wubHb7aeQnfzwM9mPQJHgEO zBjlvbL4oEa/gklu3VohZAc1daqpPajdWuOQQp4S+jUllrECQQDrITlSjvkxt8ud /vYIcEXHew3iW4nzaAH3z4PRAGZofRpk/OusGZ6cdZoYMTZcdxYTCCbZ5eeyGukW 5QCadie1AkEA6Atx8Z0F7WhLI2lGvCGy+vIOL0vBDZSma0cvLYLAXMx8duoWQ9J2 LwT7SsnRXMeq/8wlNHL7mFEf+YFZBKKlHQJAO78kfrr/zUdjwREBWaGVyZuWKpeS FTyvi1W6rAgK/bAUXeb6x69241DqyAzxQEuuW0WuAZ5u4o39/qhQH++4JQJAAepe RW1TaDNNM3yh/dmVXabz4QYSEOeiPA55YDnNFrcFbAHgryyklxzGakaiOM7ZJYVs 5TLxyr8YsXmU34nsLQJALzC8CaFXJcnU0+6+KoKX7iq1aP3X4LgP4Gianix6pfRo aV8UHnfFLRSgPdn1ZYmKtJfnsJXJYoE+o9xEErb5EQ==";
// converts the String to a PublicKey instance
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey key = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(privateKeyString.toString(), Base64.DEFAULT)));
// encrypts the message
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encrpytedText = cipher.doFinal(Base64.encode(phoneUid.getBytes("CP1252"), Base64.DEFAULT));
data = new String(encrpytedText, "CP1252");
This is the code in php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
//Set the encryption mode
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
//check for required fields
if (isset($_POST['data']) {
$data= $_POST['data'];
$key = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVIJ8H3Oszc5fWdgpwymWksF1W xkXJHIfdS6Ta1bHeqwEzPIkNf3iVk14LfaoSZpRb9Yvi/jvkXxIzJbHq6aKfnQOC 6tKIiixvVvpCfxr1eV4urDdzH9RNy9bqGdXzTQdgQi+KRx0Dcy9RNsl7ZGLAGrUF RnPI4GTdH+7wm4QogQIDAQAB
-----END PUBLIC KEY-----';
$rsa->loadKey($key );
$decrypted = $rsa->decrypt(base64_decode($data));
I solved my problem. Here is a reference for those who are doing similar thing to me. Hope that this will help other people.
In android (RSA encrypt with private key)
String encoded = null;
byte[] encrypted = null;
String plaintext = "...";
try {
String privKeyPEM = "...";
byte[] decoded = Base64.decode(privKeyPEM, Base64.DEFAULT);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, privKey);
encrypted = cipher.doFinal(plaintext.getBytes());
encoded = Base64.encodeToString(encrypted, Base64.DEFAULT);
}
catch (Exception e) {
e.printStackTrace();
}
In PHP (decrypt with public key) (using phpseclib)
$publickey = '...';
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
//decode and decrypt
$decoded = base64_decode($encrypted);
$rsa->loadKey($publickey);
$decrypted = $rsa->decrypt($decoded);
Are you passing the right parameters to cipher.doFinal?
Quoting the javadoc entry:
doFinal(byte[] inBuff, short inOffset, short inLength, byte[] outBuff, short outOffset)
Also, it looks like you're base64-encoding the plaintext before encryption when you should be encrypting the ciphertext after encryption?