error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag when importing RSA public key
Solution 1
X509EncodedKeySpec
expects DER-encoded data, not PEM-encoded. Your code will work fine if you simply discard the "BEGIN" and "END" and base64-decode the public keys contents.
final String key2 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdQudusozLmogBfU2LCO+WcM59"
+ "ycup9SxMsBNCku23PxrPMO6u//QjtWPz7istE9vkQfa6tQn1Or+SDxeHLMxEesF0"
+ "xiBEgFUhg7vjOF2SnFQQEADgUyizUIBBn1UgKNA8eP24Ux0P0M2aHMn78HIHsRcu"
+ "pNGUNW7p51HOVoIPJQIDAQAB";
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(
new X509EncodedKeySpec(DatatypeConverter.parseBase64Binary(key2)));
Solution 2
In my case the public key was contained in a certificate and I had to do something of the nature:
CertificateFactory factory = CertificateFactory.getInstance("X.509");
try {
X509Certificate cer = (X509Certificate) factory.generateCertificate(inputStream);
publicKey = cer.getPublicKey();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
Note: My file started with -----BEGIN CERTIFICATE ----
nKn
Updated on March 13, 2020Comments
-
nKn about 4 years
I've generated a RSA pair of keys (public and private). Now for testing purposes I'm trying to import the public key in
String
representation into aPublicKey
to use it within an Android project, in order to send crypted messages in RSA to a remote server which will afterwards decrypt them using the private key.public static String encryptDataRSA(final String data) throws IOException { final byte[] dataToEncrypt = data.getBytes(); byte[] encryptedData = null; try { final String keyStr = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdQudusozLmogBfU2LCO+WcM59\n" + "ycup9SxMsBNCku23PxrPMO6u//QjtWPz7istE9vkQfa6tQn1Or+SDxeHLMxEesF0\n" + "xiBEgFUhg7vjOF2SnFQQEADgUyizUIBBn1UgKNA8eP24Ux0P0M2aHMn78HIHsRcu\n" + "pNGUNW7p51HOVoIPJQIDAQAB\n" + "-----END PUBLIC KEY-----"; PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyStr.getBytes())); final Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); encryptedData = cipher.doFinal(dataToEncrypt); try { final String encryptedText = new String(Base64.encode(encryptedData, Base64.DEFAULT), "UTF-8"); return encryptedText.toString(); } catch (final UnsupportedEncodingException e1) { return null; } } catch (Exception e) { e.printStackTrace(); } return "ERROR"; }
The problem is that this is returning the following exception:
03-19 21:14:31.449: W/System.err(2713): java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag 03-19 21:14:31.480: W/System.err(2713): at org.apache.harmony.xnet.provider.jsse.OpenSSLKey.getPublicKey(OpenSSLKey.java:89) 03-19 21:14:31.480: W/System.err(2713): at org.apache.harmony.xnet.provider.jsse.OpenSSLRSAKeyFactory.engineGeneratePublic(OpenSSLRSAKeyFactory.java:47) 03-19 21:14:31.489: W/System.err(2713): at java.security.KeyFactory.generatePublic(KeyFactory.java:171) 03-19 21:14:31.489: W/System.err(2713): at com.mydomain.myproject.SecurityTools.encryptDataRSA(SecurityTools.java:85) 03-19 21:14:31.501: W/System.err(2713): at com.mydomain.myproject.MainActivity.onCreate(MainActivity.java:93) 03-19 21:14:31.501: W/System.err(2713): at android.app.Activity.performCreate(Activity.java:5133) 03-19 21:14:31.509: W/System.err(2713): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 03-19 21:14:31.521: W/System.err(2713): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175) 03-19 21:14:31.521: W/System.err(2713): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 03-19 21:14:31.529: W/System.err(2713): at android.app.ActivityThread.access$600(ActivityThread.java:141) 03-19 21:14:31.529: W/System.err(2713): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 03-19 21:14:31.541: W/System.err(2713): at android.os.Handler.dispatchMessage(Handler.java:99) 03-19 21:14:31.541: W/System.err(2713): at android.os.Looper.loop(Looper.java:137) 03-19 21:14:31.561: W/System.err(2713): at android.app.ActivityThread.main(ActivityThread.java:5103) 03-19 21:14:31.571: W/System.err(2713): at java.lang.reflect.Method.invokeNative(Native Method) 03-19 21:14:31.581: W/System.err(2713): at java.lang.reflect.Method.invoke(Method.java:525) 03-19 21:14:31.592: W/System.err(2713): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 03-19 21:14:31.601: W/System.err(2713): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 03-19 21:14:31.609: W/System.err(2713): at dalvik.system.NativeStart.main(Native Method) 03-19 21:14:31.621: W/System.err(2713): Caused by: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag 03-19 21:14:31.649: W/System.err(2713): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.d2i_PUBKEY(Native Method) 03-19 21:14:31.649: W/System.err(2713): at org.apache.harmony.xnet.provider.jsse.OpenSSLKey.getPublicKey(OpenSSLKey.java:87) 03-19 21:14:31.663: W/System.err(2713): ... 18 more
The exception points to this line:
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
Why is this returning this exception and how to solve it? Thanks.
-
nKn about 10 yearsThanks so much for this! :-)
-
Suyash Dixit over 8 yearsThanks. I was facing the same problem. Looking at your answer I realised that I also had "\n" in the end. I removed it and everything went fine.
-
Diego Palomar almost 7 yearsI had the same problem but I have't realised I could get the public key from the certificate itself... you made my day dude, thank you! :D
-
madhuri H R over 5 yearsCannot find DatatypeConverter. Is it builtin method ?