2

I have a problem to create a public key from a public key text. I found the solution from this link Creating RSA Public Key From String. They mentioned Bouncy Castle (lightweight API) as a library to solve the InvalidKeySpecException error when converting a public key string to a RSA public key. But this solution failed with my case. The program throws an exception here

Exception in thread "main" java.lang.IllegalArgumentException: Bad sequence size: 9

Creating RSA Public Key From String

   String publicKeyB64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3AQKDhhtcM5A1a8R9/VX" +
            "mrocKGaQlat2/MRFy/Y1fTabYyKkfgaRXyrHiRn+imq3ljEgx/vLRTTPtLt8H79a" +
            "iMU6WJkQwG504NCnDRVB9DZBoAYDtBkjtje7I2Xs3tzvlNwM0bcCmmj/6QE9rHEv" +
            "xhvvXO8M332hINORLNiCF6NvYHrIVSa8EU4F0bnlWpoNi0YhP45uyOOuPpVmsaxp" +
            "MWOycf3nTICKK5BDylnVO7kMcL1utJxOOb1fsotaLuge4fF84DG4cPpLZko3ksB/" +
            "voOLTDv5QRsn++8qRciK4sptlnOs8g2TrXjE/rZlP9QmpUV4a3iQ1WmsqWQVizmw" +
            "PwIDAQAB";

    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);

So I'm really expecting advice to handle this.

Lee Dat
  • 155
  • 1
  • 6
  • 20
  • Your data isn't an RSA public key, **it's an RSA private key** in PKCS1 aka CRT form, which allows extracting either private or public key fields. Use `org.bouncycastle.asn1.pkcs.RSAPrivateKey` -- and don't use that key for anything, since it's been compromised. – dave_thompson_085 Apr 09 '19 at 07:40
  • I'm sorry because of this. I updated the public key but it throws **Exception in thread "main" java.lang.IllegalArgumentException: illegal object in getInstance: org.bouncycastle.asn1.DLSequence** – Lee Dat Apr 09 '19 at 10:19

2 Answers2

4

The data you have now edited is a public key, but not in PKCS1 format; it is in the more common (and usually more useful) X.509 SubjectPublicKeyInfo format. This difference is explained in the Q you linked. While this format is supported by BouncyCastle, it is also supported directly by Java crypto (JCA) using the (technically imprecise) name X509EncodedKeySpec, so it is much simpler to just do:

byte[] decoded = Base64.getDecoder().decode(publicKeyB64);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey generatedPublic = kf.generatePublic(new X509EncodedKeySpec(decoded));
dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70
0

If your public key is proper, then you should be able to read it on command line in order to break down the problem. Try using these commands :

$ openssl rsa -inform PEM -pubin -in pub.key -text -noout
$ openssl pkey -inform PEM -pubin -in pub.key -text -noout

Replace "pub.key" with your public key file.

Gautam
  • 1,862
  • 9
  • 16
  • That would work only for a (public) key in X.509 SubjectPublicKeyInfo format, which OpenSSL calls PUBKEY and Java calls X509EncodedKeySpec, AND only if you add the correct PEM BEGIN and END lines. That is not the only valid representation for an RSA public key -- although the key in this Q isn't _any_ representation of RSA public key. – dave_thompson_085 Apr 09 '19 at 07:38
  • I'm sorry because of this. I updated the public key at my code but it throws **Exception in thread "main" java.lang.IllegalArgumentException: illegal object in getInstance: org.bouncycastle.asn1.DLSequence** – Lee Dat Apr 09 '19 at 10:20