Reputation: 41
I'm trying to encrypt data in android side and decrypt it in php side i'm using phpseclib in php to generate public/private keys
after i generate keys this public key i got in PHP side :
-----BEGIN RSA PUBLIC KEY-----".
"MIGJAoGBAKks62Itns2uU/dVZJ4kCkMinHgyeh/rdMD53a4Zu2a76OIJvdSZ8q4c".
"YTWvPj0giefVtMc7tV4c6AAw04jyIfmCTvcQUlHI+sspHxXDlQTagNoxCuA29b5L".
"9MKO6Ok0LwF9rGgTywC1heNEulZz9ISn9FQDazJT+Bd9cnNOrJRdAgMBAAE=".
"-----END RSA PUBLIC KEY-----
and then i encoded it to base64 and got this base64 encoded key
LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tTUlHSkFvR0JBS2tzNjJJdG5zMnVVL2RWWko0a0NrTWluSGd5ZWgvcmRNRDUzYTRadTJhNzZPSUp2ZFNaOHE0Y1lUV3ZQajBnaWVmVnRNYzd0VjRjNkFBdzA0anlJZm1DVHZjUVVsSEkrc3NwSHhYRGxRVGFnTm94Q3VBMjliNUw5TUtPNk9rMEx3RjlyR2dUeXdDMWhlTkV1bFp6OUlTbjlGUURhekpUK0JkOWNuTk9ySlJkQWdNQkFBRT0tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0t
i copied it to android side to encrypt data using it but i got InvalidKeySpecException
Android Side Code:
public static byte[] encrypt(String text) {
byte[] encodedPublicKey= Base64.decode("LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tTUlHSkFvR0JBS2tzNjJJdG5zMnVVL2RWWko0a0NrTWluSGd5ZWgvcmRNRDUzYTRadTJhNzZPSUp2ZFNaOHE0Y1lUV3ZQajBnaWVmVnRNYzd0VjRjNkFBdzA0anlJZm1DVHZjUVVsSEkrc3NwSHhYRGxRVGFnTm94Q3VBMjliNUw5TUtPNk9rMEx3RjlyR2dUeXdDMWhlTkV1bFp6OUlTbjlGUURhekpUK0JkOWNuTk9ySlJkQWdNQkFBRT0tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0t", Base64.DEFAULT);
PublicKey publicKey=null;
KeyFactory keyFactory = null;
try {
keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey);
publicKey = keyFactory.generatePublic(publicKeySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}catch (InvalidKeySpecException e) {
e.printStackTrace();
}
byte[] cipherText = null;
try {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance("RSA");
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipherText = cipher.doFinal(text.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
Upvotes: 4
Views: 1910
Reputation: 93978
The following code parses the PEM, feeds it to a PKCS#1 RSAPublicKey
class parser from BouncyCastle, then constructs a JCE RSAPublicKey
from the modulus and the exponent. The rest is error handling, the key itself and a main method to show it works.
For Android you may need to use Spongy Castle instead.
package nl.owlstead.stackoverflow;
import java.io.IOException;
import java.io.StringReader;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
public final class RSAPublicKeyFromOpenSSL_PKCS1_PEM {
private static final String PEM = "-----BEGIN RSA PUBLIC KEY-----\r\n"
+ "MIGJAoGBAKks62Itns2uU/dVZJ4kCkMinHgyeh/rdMD53a4Zu2a76OIJvdSZ8q4c\r\n"
+ "YTWvPj0giefVtMc7tV4c6AAw04jyIfmCTvcQUlHI+sspHxXDlQTagNoxCuA29b5L\r\n"
+ "9MKO6Ok0LwF9rGgTywC1heNEulZz9ISn9FQDazJT+Bd9cnNOrJRdAgMBAAE=\r\n"
+ "-----END RSA PUBLIC KEY-----\r\n";
public static RSAPublicKey parsePEM(final String pem)
throws IllegalArgumentException {
// --- read PEM object
final PemObject readPemObject;
try (final PemReader reader = new PemReader(new StringReader(PEM))) {
readPemObject = reader.readPemObject();
} catch (final IOException e) {
throw new IllegalArgumentException("Not a PEM object", e);
}
if (!readPemObject.getType().equalsIgnoreCase("RSA PUBLIC KEY")) {
throw new IllegalArgumentException("Not a public key");
}
final byte[] pemContent = readPemObject.getContent();
// --- create Bouncy Castle PKCS#1 public key
final org.bouncycastle.asn1.pkcs.RSAPublicKey pkcs1PublicKey;
try {
pkcs1PublicKey = org.bouncycastle.asn1.pkcs.RSAPublicKey
.getInstance(pemContent);
} catch (final Exception e) {
throw new IllegalArgumentException(
"Could not parse BER PKCS#1 public key structure", e);
}
// --- convert to JCE RSAPublicKey
final RSAPublicKeySpec spec = new RSAPublicKeySpec(
pkcs1PublicKey.getModulus(), pkcs1PublicKey.getPublicExponent());
final KeyFactory rsaKeyFact;
try {
rsaKeyFact = KeyFactory.getInstance("RSA");
} catch (final NoSuchAlgorithmException e) {
throw new IllegalStateException("RSA KeyFactory should be available", e);
}
try {
return (RSAPublicKey) rsaKeyFact.generatePublic(spec);
} catch (InvalidKeySpecException e) {
throw new IllegalArgumentException(
"Invalid RSA public key, modulus and/or exponent invalid", e);
}
}
public static void main(final String ... args) throws Exception {
final RSAPublicKey publicKey = parsePEM(PEM);
System.out.println(publicKey);
}
}
Upvotes: 2