views:

54

answers:

2

Have a String being sent from in the below format:

-----BEGIN RSA PUBLIC KEY-----
MIGHAoGBANAahj75ZIz9nXqW2H83nGcUao4wNyYZ9Z1kiNTUYQl7ob/RBmDzs5rY
mUahXAg0qyS7+a55eU/csShf5ATGzAXv+DDPcz8HrSTcHMEFpuyYooX6PrIZ07Ma
XtsJ2J4mhlySI5uOZVRDoaFY53MPQx5gud2quDz759IN/0gnDEEVAgED
-----END RSA PUBLIC KEY-----

How do i construct a PublicKey Object from this string ? Have tried the below Remove the header and footer and base64 decode the buffer

public static PublicKey getFromString(String keystr) throws Exception
  {
  //String S1= asciiToHex(keystr);
   byte[] keyBytes = new sun.misc.BASE64Decoder().decodeBuffer(keystr);
   X509EncodedKeySpec spec =
       new X509EncodedKeySpec(keyBytes);
     KeyFactory kf = KeyFactory.getInstance("RSA");
     return kf.generatePublic(spec);

  }

This fails either as an invalid key format or will get below error

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
 at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:188)
 at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
 at PublicKeyReader.getFromString(PublicKeyReader.java:30)
 at Tst.main(Tst.java:36)

The Key is being generated thro the API of openSSL PEM_write_bio_RSAPublicKey(bio, rsa);

+2  A: 

by calling PEM_write_bio_RSAPublicKey only the key modulus and public exponent are encoded into the output PEM data. However the X509EncodedKeySpec is expected this ASN.1 key format:

 SubjectPublicKeyInfo ::= SEQUENCE {
   algorithm AlgorithmIdentifier,
   subjectPublicKey BIT STRING }

You should use the PEM_write_bio_PUBKEY function which encodes the public key using the SubjectPublicKeyInfo structure which as expected by X509EncodedKeySpec

An other possible solution to decode the key. Unfortunately I don't think it is possible to do only with the standard JDK API but it can be done with the Bouncycastle library

import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.x509.RSAPublicKeyStructure;

public static PublicKey getFromString(String keystr) throws Exception
{
  //String S1= asciiToHex(keystr);
   byte[] keyBytes = new sun.misc.BASE64Decoder().decodeBuffer(keystr);
   ASN1InputStream in = new ASNASN1InputStream(keyBytes);
   DERObject obj = in.readObject();
   RSAPublicKeyStructure pStruct = RSAPublicKeyStructure.getInstance(obj);
   RSAPublicKeySpec spec = new RSAPublicKeySpec(pStrcut.getModulus(), pStruct.getPublicExponent());
   KeyFactory kf = KeyFactory.getInstance("RSA");
   return kf.generatePublic(spec);
}
Jcs
how or where should the SubjectPublicKeyInfo structure be specified?
MSSV
The SubjectPublicKeyInfo structure is specified in the RFC 5280 (http://tools.ietf.org/html/rfc5280) and the public key structures are specified in the RFC 3279 (http://tools.ietf.org/html/rfc3279)
Jcs
The Client key is received so will not be able to change the format.Can you suggest any other way of loading this key and getting the details thro JCE example .
MSSV
I updated the response and added a potential solution
Jcs