I'm desperately trying to encrypt a message using asymmetric public / private key cryptography on an Android.
I'm on Windows and I've generated a public and private key using puttygen. I'm not sure what difference it makes but I've selected SSH-2 RSA. Here is the public key:
AAAAB3NzaC1yc2EAAAABJQAAAQEAh63orUzl0UTd7jj0KNYJg1+kNnty0QHyJu0r
Cajf5Kl7qWJaGXPfwsG8Qt3teafs5sv0JBSinab0s/5wfQmd1QPpXTMP93Wc4ucp
1VC/9B2o8XVi4fKoGTehB48yrSfI6KF2AIeASM1jUswydKxsuS4AS2mLGV/HuoKD
huMfCsRc8qK5zGQfVCoZTbQ66Z1yKdAzxMUuGmiTp7pVsle/P/UGbm6yFiee5r1/
dOR2CDyR6CP09Jaj7KSGfGuwPryCXPjEce1oCbN/FlLHVb7T1B5f6xhq+oY+Ij13
1IZPfShV8cs2kYKjsle2s23V5urSdWFv2tEcSJcpkUm2FlPdQw==
I've copied this to a text file in my main/assets folder. I read this in like so:
InputStream input = context.getAssets().open(filename);
This is then read in to a byte array through a fairly standard ByteArrayOutputStream method.
I then try and convert that to a public key as such:
public static PublicKey getPublicKey(byte[] keyBytes){
PublicKey publicKey = null;
if(keyBytes != null) {
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = null;
try {
kf = KeyFactory.getInstance("RSA");
publicKey = kf.generatePublic(spec);
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "NoSuchAlgorithmException");
e.printStackTrace();
} catch (InvalidKeySpecException e) {
Log.e(TAG, "InvalidKeySpecException " + e.getMessage());
e.printStackTrace();
}
}
return publicKey;
}
Problem is I keep getting this error:
InvalidKeySpecException java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
I've been attacking this for hours, and can't seem to get around it. Please please any suggestions welcome.
I've tried Base64 as such:
byte[] tempNewKey = Base64.decode(keyBytes, Base64.DEFAULT);
Which makes no difference and I've also tried using
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(module), new BigInteger(exponent));
However putty doesn't tell me anything about an exponent? If I go ahead with this method I don't get the same error, but if I try and decrypt with my private key I just get gibberish.
Really hope you can help. Many Thanks
SSH keys are not X509 compatible keys. They are stored in a SSH proprietary format. You'll need a SSH capable libary to retrieve the key value.
If SSH functionality is not required then it is possible to generate keys in Java (using the keytool command line or KeyPairGenerator.
Alternatively it is also possible to use external applications or libraries such as the openssl command line. In the case of OpenSSL specify DER as output. Java expects a DER encoded SubjectPublicKeyInfo structure for X509EncodedKeySpec.
Related
I am trying to get RSA PublicKey for jwt token validation in Java but my attempts fail with this exception:
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format.
My code:
String publicKeyString = "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBMk5pKytLeUpVaDhLYklLVU51OG0KUk5lRCtrU2tXZEh6MjBvSFZYK0g0cVd4WHlJSTk0MVdJUFU2WFpPc3lMeE9qZU1hb0ZRanJ6bDFwYnZQekUyRQpwMmhlK1BnQ1JteDNqOFlMVVd3dGpuQTVwTTFLWDhpNG5vTUw4RmlWY1U2NkE5RjRkZmRQR2MzY0tQQ2ZPbnorCmtBbW5qRllzajYzRCsrTThYSDRWaS9Vc0V3T1lzU05FR2RncUd2OTlTNHpVRzFzd2FqZ1NnODhvbTVaOC9Ja1AKY01LT3cvWkpvVHNDN3l1VlJnTC9xa3EwaDVkM2lXVXNNdXl1K0xoblRhTko4bW9WQmpJT2lQQkR0cEQyN1lzNgpCSGs1dEdBa3ZHZDg0N3c4SjVEeTFzYWlQS0pxelltcUx5akg3b3VlcERFczdEZ2UxZUlJeno5a1RnSkhKZHVzCnd3SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K";
PublicKey publicKey = getPublicKey(Base64.getDecoder().decode(publicKeyString), "RSA");
And getPublicKey function:
private static PublicKey getPublicKey(byte[] keyBytes, String algorithm) {
PublicKey publicKey = null;
try {
KeyFactory kf = KeyFactory.getInstance(algorithm);
EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
System.out.println(keySpec.getFormat());
publicKey = kf.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
System.out.println("Could not reconstruct the public key, the given algorithm could not be found.");
} catch (InvalidKeySpecException e) {
e.printStackTrace();
System.out.println("Could not reconstruct the public key");
}
return publicKey;
}
I know that there are many similar questions dealing with the same exception being thrown and I've read many of them and tried the solutions but nothing worked. I would appreciate any help.
Your data is not the base64 encoding of an actual X.509 publickey block (SubjectPublicKeyInfo) as required by Java crypto. It actually is the base64 encoding of a PEM file which is itself structured and encoded. Moreover this PEM file is labelled as containing 'RSA PUBLIC KEY' which would be the 'raw' PKCS1 form and wrong for Java, but fortunately whatever created this PEM file was defective and the body of the PEM file actually is an X.509 SubjectPublicKeyInfo which should have PEM label 'PUBLIC KEY' per RFC7468 #13. (RFC5280 is a profile of X.509.)
Thus you need to decode your string to PEM, then parse the PEM to get X.509:
String orig = "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBMk5pKytLeUpVaDhLYklLVU51OG0KUk5lRCtrU2tXZEh6MjBvSFZYK0g0cVd4WHlJSTk0MVdJUFU2WFpPc3lMeE9qZU1hb0ZRanJ6bDFwYnZQekUyRQpwMmhlK1BnQ1JteDNqOFlMVVd3dGpuQTVwTTFLWDhpNG5vTUw4RmlWY1U2NkE5RjRkZmRQR2MzY0tQQ2ZPbnorCmtBbW5qRllzajYzRCsrTThYSDRWaS9Vc0V3T1lzU05FR2RncUd2OTlTNHpVRzFzd2FqZ1NnODhvbTVaOC9Ja1AKY01LT3cvWkpvVHNDN3l1VlJnTC9xa3EwaDVkM2lXVXNNdXl1K0xoblRhTko4bW9WQmpJT2lQQkR0cEQyN1lzNgpCSGs1dEdBa3ZHZDg0N3c4SjVEeTFzYWlQS0pxelltcUx5akg3b3VlcERFczdEZ2UxZUlJeno5a1RnSkhKZHVzCnd3SURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K";
String pem = new String(Base64.getDecoder().decode(orig)); // default cs okay for PEM
String[] lines = pem.split("\n"); lines[0] = lines[lines.length-1] = ""; String body = String.join("", lines);
// in general split on "\r?\n" (or delete "\r" and split on "\n")
//or instead:
//String body = pem.replaceAll("-----(BEGIN|END) RSA PUBLIC KEY-----\n","").replaceAll("\n", ""); // or "\r?\n"
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey key = kf.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(body)));
// for test only:
System.out.println ( ((java.security.interfaces.RSAPublicKey)key).getModulus() );
Note your specific data has PEM using single-character (NL aka \n) linebreaks, but PEM in general can use either NL or CRLF (\r\n); see my comments.
Does somebody know how I can create an RSA key in C++ from an encoded byte array?
My problem is that I try to develop a C++ client that is interacting with a server which is coded in Java.
Well in Java the client receives the rsa key encoded as an byte array, decodes it to a RSA RSAPublicKey and encrypts a message with this key.
The java server/client code:
public static PublicKey decodePublicKey(byte[] p_75896_0_)
{
try
{
X509EncodedKeySpec var1 = new X509EncodedKeySpec(p_75896_0_);
KeyFactory var2 = KeyFactory.getInstance("RSA");
return var2.generatePublic(var1);
}
catch (NoSuchAlgorithmException var3)
{
;
}
catch (InvalidKeySpecException var4)
{
;
}
field_180198_a.error("Public key reconstitute failed!");
return null;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
this.publicKey = CryptManager.decodePublicKey(data.readByteArray());
After that the client is doing some encrypting stuff with his key.
The key gets sent like this:
public static final KeyPair keys;
static
{
try
{
KeyPairGenerator generator = KeyPairGenerator.getInstance( "RSA" );
generator.initialize( 1024 );
keys = generator.generateKeyPair();
} catch ( NoSuchAlgorithmException ex )
{
throw new ExceptionInInitializerError( ex );
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
byte[] pubKey = keys.getPublic().getEncoded();
writeBytes(pubKey);
My problem is how to get the key from the byte array in C++.
Update:
Im currently working on this code:
char* publicKey = ...
int publicKeyLength = 162;
EVP_PKEY* key = EVP_PKEY_new();
if(d2i_PUBKEY(&key, (const unsigned char**) &publicKey, publicKeyLength) != 0){
logError("Problem!");
}
logMessage("Key: "+to_string((uint64_t) (void*) key));
Well my problem now is that i have an SIGSEGV error on the third line and dont know what this course. Well the key should be valid.
What Java returns for the public key is a SubjectPublicKeyInfo structure, which doesn't just contain the (PKCS#1 encoded) values for the public key, but also the key identifier etc.
So to decode this you have to type "decode SubjectPublicKeyInfo openssl" in your favorite search engine. Then you'll find (after some scrolling) the following information from here:
d2i_PUBKEY() and i2d_PUBKEY() decode and encode an EVP_PKEY structure
using SubjectPublicKeyInfo format. They otherwise follow the conventions
of other ASN.1 functions such as d2i_X509().
Obviously you'd need the decoding algorithm.
Note that openssl is C so beware of buffer overruns when decoding stuff. I'd rather have a 1024 bit RSA key that is used with secure software than a 2048 bit key with software full of buffer overruns.
Needless to say you need to trust the public key before importing it. There is a reason why it is called the public key infrastructure (PKI).
I've generated this test public key using 1024 RSA and then encoded it to DER and Base64 in another coding platform. I copied the key into a string in Android/Eclipse and I am trying to turn it into a public key using KeyFactory. It just keeps giving me an InvalidKeySpecException no matter what I try. Any advice at all would be appreciated.
private void prepKeys() {
String AppKeyPub = "MIGHAoGBAOX+TFdFVIKYyCVxWlnbGYbmgkkmHmEv2qStZzAFt6NVqKPLK989Ow0RcqcDTZaZBfO5" +
"5JSVHNIKoqULELruACfqtGoATfgwBp4Owfww8M891gKNSlI/M0yzDQHns5CKwPE01jD6qGZ8/2IZ" +
"OjLJNH6qC9At8iMCbPe9GeXIPFWRAgER";
// create the key factory
try {
KeyFactory kFactory = KeyFactory.getInstance("RSA");
// decode base64 of your key
byte yourKey[] = Base64.decode(AppKeyPub,0);
// generate the public key
X509EncodedKeySpec spec = new X509EncodedKeySpec(yourKey);
PublicKey publicKey = (PublicKey) kFactory.generatePublic(spec);
System.out.println("Public Key: " + publicKey);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The key you have is in PKCS#1 format instead of SubjectPublicKeyInfo structure that Java accepts. PKCS#1 is the encoding of the RSA parameters only and lacks things such as an algorithm identifier. SubjectPublicKeyInfo uses PKCS#1 internally - for RSA public keys anyway.
As the PKCS#1 public key is at the end of the SubjectPublicKeyInfo structure it is possible to simply prefix the bytes so that they become an RSA SubjectPublicKeyInfo. That solution is easier to perform without additional libraries such as Bouncy Castle. So if you need to go without an external library then you may have a look at my answer here.
Alternatively a simple BER decoder could be written to decode the structure into the two BigInteger values. The structure itself is not that complicated but the BER/DER length encoding takes some getting used to.
However, you can also use Bouncy Castle (lightweight API) to solve your issues:
String publicKeyB64 = "MIGHAoGBAOX+TFdFVIKYyCVxWlnbGYbmgkkmHmEv2qStZzAFt6NVqKPLK989Ow0RcqcDTZaZBfO5"
+ "5JSVHNIKoqULELruACfqtGoATfgwBp4Owfww8M891gKNSlI/M0yzDQHns5CKwPE01jD6qGZ8/2IZ"
+ "OjLJNH6qC9At8iMCbPe9GeXIPFWRAgER";
// ok, you may need to use the Base64 decoder of bouncy or Android instead
byte[] decoded = Base64.getDecoder().decode(publicKeyB64);
org.bouncycastle.asn1.pkcs.RSAPublicKey pkcs1PublicKey = org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(decoded);
BigInteger modulus = pkcs1PublicKey.getModulus();
BigInteger publicExponent = pkcs1PublicKey.getPublicExponent();
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, publicExponent);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey generatedPublic = kf.generatePublic(keySpec);
System.out.printf("Modulus: %X%n", modulus);
System.out.printf("Public exponent: %d ... 17? Why?%n", publicExponent); // 17? OK.
System.out.printf("See, Java class result: %s, is RSAPublicKey: %b%n", generatedPublic.getClass().getName(), generatedPublic instanceof RSAPublicKey);
As you can see it actually only requires a single class as interface, although that is of course backed up with the entire ASN.1/BER decoder functionality within Bouncy Castle.
Note that it may be required to change the Base 64 decoder to the Android specific one (android.util.Base64). This code was tested on an equivalent Java runtime.
For those who dont want to use Bouncy Castle
public class RSAKeySeperation {
public static void main(String[] args) throws InvalidKeySpecException, NoSuchAlgorithmException {
String publicKeyB64 = "MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQBV8xakN/wOsB6qHpyMigk/5PrSxxd6tKTJsyMIq5f9npzZue0mI4H2o8toYImtRk6VHhcldo0t7UwsQXmFMk7D"
+ "i3C53Xwfk7yEFSkXGpdtp/7fbqNnjVoJl/EPcgoDsTPrHYF/HgtmbhzuYvYeY1zpV0d2uYpFxAuqkE9FreuuH0iI8xODFe5NzRevXH116elwdCGINeAecHKgiWe"
+ "bGpRPml0lagrfi0qoQvNScmi/WIN2nFcI3sQFCq3HNYDBKDhO0AEKPB2FjvoEheJJwTs5URCYsJglYyxEUon3w6KuhVa+hzYJUAgNTCsrAhQCUlX4+5LOGlwI5gonm1DYvJJZAgMBAAEB";
byte[] decoded = Base64.getDecoder().decode(publicKeyB64);
X509EncodedKeySpec spec =
new X509EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKey generatePublic = (RSAPublicKey) kf.generatePublic(spec);
BigInteger modulus = generatePublic.getModulus();
System.out.println(modulus);
BigInteger exponent = generatePublic.getPublicExponent();
System.out.println(exponent);
}
}
For obvious security reasons i need to encrypt and decrypt User's PIN codes with RSA private and public key, I have found working solution, which looks like:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(512);
KeyPair rsaKeyPair = kpg.genKeyPair();
byte[] txt = "This is a secret message.".getBytes();
System.out.println("Original clear message: " + new String(txt));
// encrypt
Cipher cipher;
try {
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, rsaKeyPair.getPublic());
txt = cipher.doFinal(txt);
} catch (Throwable e) {
e.printStackTrace();
return;
}
System.out.println("Encrypted message: " + new String(txt));
// decrypt
try {
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, rsaKeyPair.getPrivate());
txt = cipher.doFinal(txt);
} catch (Throwable e) {
e.printStackTrace();
return;
}
System.out.println("Decrypted message: " + new String(txt));
}
everything works fine, but in this example key-pair is not static and generate new values everytime, but I need to use same keys, which are represented as String variables:
public static final String PrivateKey = "MIICXAIBAAKBgQDx0PSJr6zEP9914k1eM+sS8/eW+FenhBQI/jf6ARe8kZHFig9Y"
+ bla bla bla
+ "wdK3jBzObK319yNFr/2LukNZ9Bgv7fS78roBvxbe2gI=";
public static final String PublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDx0PSJr6zEP9914k1eM+sS8/eW"
+ bla bla bla
+ "jYo5w2Nhxe2cukCQMQIDAQAB";
Is there any way to cast these variables to PublicKey and PrivateKey Class?
If I understand what you want, to obtain PublicKey and PrivateKey instances from your static variables you can do, for example, this way:
private static final String privateKeyString = "...";
private static PrivateKey privateKey;
private static final String publicKeyString = "...";
private static PublicKey publicKey;
static {
KeyFactory kf;
try {
kf = KeyFactory.getInstance("RSA");
byte[] encodedPv = Base64.decodeBase64(privateKeyString);
PKCS8EncodedKeySpec keySpecPv = new PKCS8EncodedKeySpec(encodedPv);
privateKey = kf.generatePrivate(keySpecPv);
byte[] encodedPb = Base64.decodeBase64(publicKeyString);
X509EncodedKeySpec keySpecPb = new X509EncodedKeySpec(encodedPb);
publicKey = kf.generatePublic(keySpecPb);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
}
}
After (mostly) concurring with #JB that passwords (usually) shouldn't be encrypted, they should be "hashed" -- using a method specifically designed to "stretch" and salt such as scrypt, not a fast hash like SHA-1 -- and also noting that RSA-512 as used in your original code is broken and even RSA-1024 as apparently used in your modification is considered weak:
Your PrivateKey value appears (from its beginning) to be base64 of a plain PKCS#1 DER encoding, which basically is used only by OpenSSL and things that use OpenSSL (format) like older versions of OpenSSH. The Java standard "Sun" providers do not handle this, although I think BouncyCastle might if you want to explore that. For Sun you need to convert it to binary DER from base64; wrap it into PKCS#8 format (which in binary is just adding a header and maybe EOC trailers because the algorithm-specific part of PKCS#8 for RSA is PKCS#1); and put it in a PKCS8EncodedKeySpec and run it through generatePrivate of a KeyFactory of type RSA. See
http://docs.oracle.com/javase/8/docs/api/java/util/Base64.html (Java8 only)
http://docs.oracle.com/javase/8/docs/api/java/security/KeyFactory.html
https://www.rfc-editor.org/rfc/rfc5208#section-5 for the structure of unencrypted PKCS#8 (Java doesn't do the encrypted format in section 6) and look at the publickey form for the OID for RSA.
Alternatively add the header/trailer to make it proper PEM, use OpenSSL to convert it to PKCS#8 (unencrypted), and optionally binary at the same time, and run that through generatePrivate.
Your PublicKey similarly appears to be base64 of an X.509 SubjectPublicKeyInfo encoding, which OpenSSL (but not OpenSSH) uses and standard Java does support under the name "X.509". So just convert from base64 to binary, put in an X509EncodedKeySpec, and run through generatePublic of the RSA KeyFactory. Note if your encryption will be done remote or distributed, which is the usual scenario for publickey-encryption, the encryptor must be certain to use the correct publickey; if an attacker can substitute a wrong publickey they can decrypt and steal at least some of your supposedly secure data. That's why real PK systems don't use a plain publickey, they use a certificate, either X.509 like SSL/TLS and S/MIME, or web-of-trust like PGP.
I got this running doing the following:
public Key loadPrivateKey(String stored) throws GeneralSecurityException {
PKCS8EncodedKeySpec keySpec =
new PKCS8EncodedKeySpec(
Base64.getDecoder().decode(stored.getBytes(StandardCharsets.UTF_8)));
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(keySpec);
}
public Key loadPublicKey(String stored) throws GeneralSecurityException {
byte[] data = Base64.getDecoder().decode(stored.getBytes(StandardCharsets.UTF_8));
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance("RSA");
return fact.generatePublic(spec);
}
You must also to remove -----BEGIN PRIVATE KEY-----, -----END PRIVATE KEY----- and all \n from the strings that contain you keys.
I am encrypting using Bouncy Castle. I am using RSA and public key is stored in PEM file. I am finding that when I run the code in simple console project (not Android project) everything works fine - meaning the encrypted string can be decrypted using the private key. However, when I run the same code in Android app, the encrypted byte array is different for the same public key and is not recognized as valid encryption for the given key pair.
Details:
Here is the code that encrypts string using Bouncy Castle and taken out of the console project. This one works fine and produces the encrypted string which is valid encryption for the key pair and can be decrypted.
private static void encrypt() {
try {
//This example uses the Bouncy Castle library
Security.addProvider(new BouncyCastleProvider());
String plainText = "This needs to be encrypted";
String public_key_file = "PublicKey.pem";
//Load public key
PEMParser parser = new PEMParser(new FileReader(public_key_file));
Object key = parser.readObject();
parser.close();
PublicKey pubKey = null;
if (key instanceof SubjectPublicKeyInfo) {
SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) key;
pubKey = KeyFactory.getInstance("RSA").generatePublic
(new X509EncodedKeySpec(spki.getEncoded()));
}
//Encrypt the plain text
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted_data = cipher.doFinal(plainText.getBytes());
String encoded_data = new String(Base64.encode(encrypted_data));
System.out.println("Encrypted Value:");
System.out.println(encoded_data);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
Now here is the code taken out of the Android app. The only important difference is that the key file is read from Assets folder. This code also produces encrypted string but it is not valid for the key pair and can't be decrypted.
public void encrypt(Context context) {
try {
//This example uses the Bouncy Castle library
Security.addProvider(new BouncyCastleProvider());
String plainText = "This needs to be encrypted";
String public_key_file = "PublicKey.pem";
//Load public key
InputStream inputStream = context.getAssets().open(public_key_file);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
// read from the input stream reader
PEMParser parser = new PEMParser(inputStreamReader);
Object key = parser.readObject();
parser.close();
PublicKey pubKey = null;
if (key instanceof SubjectPublicKeyInfo) {
SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) key;
pubKey = KeyFactory.getInstance("RSA").generatePublic
(new X509EncodedKeySpec(spki.getEncoded()));
}
//Encrypt the plain text
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted_data = cipher.doFinal(plainText.getBytes());
String encoded_data =
new String(Base64.encode(encrypted_data));
Log.d("MyApp", "Encrypted Value:");
Log.d("MyApp", encoded_data);
} catch (Exception ex) {
Log.d("MyApp", ex.getMessage());
}
}
In both the cases, following things are same:
Public Key
Actual code written (with difference of reading from Assets folder and logging to Logcat)
JDK version (1.7)
Bouncy Castle libraries (bcpkix-jdk15on-152.jar and bcprov-jdk15on-152.jar)
What's different: The environment. One is console program and the other is Android App.
On further investigation while debugging
I observed that when running the console program the KeyFactory returns instance of "sun.security.rsa.RSAPublicKeyImpl". However when running android app, the KeyFactory returns instance of "com.android.org.conscrypt.OpenSSLRSAPublicKey". Not sure if that's the problem. The encrypted byte array is different for same plain text and public key.
Any help is greatly appreciated.
Thanks in Advance,
Sandeep