I have an unformatted public key in a properties file, meaning it only contains the public key hexa value:
K_PUB_CCE = 3082010902820100A515281FAC9ABAA8E966DC1B6EC0F1C431674B4E7BCB718955A34211D5CC6BA53F2C93F67C030A970D4E41341949E6BC3F9336287EEA21702FE663C83D4BAFEE2AAA2EEE7A6AFDC423A159D420E42ABDE2792080249C5D6E25367F804333665CAFB79FD5A59D70B9F69159F4EDAD2DA4B434F41D0EC5217808E7D91FF547C83774E4BDE813302E16377156E52CAF02D1E68371D536AA0E7E32DE484FF4863538DCBC69E8D3E3C1F3CECEA9861DA5516A06D3208F6363B86CF66641BE18C4F41ABD7F1B5CDC9BD964914515DDC58F32F49437BD7E89431C8F484BBCEBA86A5FFF74E01D12E6D1D7EBBF6E5DCD7A9134BF27185F4BD347B23007FF366C0009E14F0203010001
As you can see, it's 538 hexas long. What I wanna achieve is to obtain a java.security.PublicKey with this value.
But when using this method:
private PublicKey createPublicKey(String stringPublicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] bytesKey= Hex.decodeHex(stringPublicKey.toCharArray());
X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(bytesKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(encodedKeySpec);
}
I get the following exception:
java.security.InvalidKeyException: IOException: algid parse error, not a sequence
What am I doing wrong? Is there any other key spec class I should be using?
What you have is almost the hex encoding of the DER encoding of a PKCS#1 public key. This is not the same as the SubjectPublicKeyInfo that is handled by the X509EncodedKeySpec class. I say almost because the encoding is slightly buggy. The modulus is encoded as a negative integer, which is wrong.
The easiest way to handle this is to simply break out the modulus and exponent by hand as in the following small example using your hex string.
It is rather bothersome to store the public key as a base64 String and then convert it back (since also depending on the platform the format might vary). Using a KeyStore file would be much easier.
In case this is not an option for you, there is another way. You need to input your key (modulus) and the used exponent. The exponent is usually 65537, but there are also ways to find that out for sure (see references). This works for me:
Edit:
I am sorry, I just saw that you use a Hex string. The original RSA format should be some base64 encoded value. Since you already have the hex value, the BigInteger creation for the modulus should be different (please see source code edit). Also as mentioned in the comments below, the platform issue does not arise for the Hex string or the Base64 format. The only thing to be aware of here, is to specify a format (such as UTF-8) when encoding from String to Base64 with getBytes(). If no format is specified, the platform default will be used.
References:
RSA exponent 65537
Convert RSA Hex String to PublicKey
How to find out your exponent
About the hex key length/format
Encoding String to Base64