I have my Private and Public keys in a String in base64 which where encoded using ANS1 DER. I tried creating the instance of a java PrivateKey
and PublicKey
:
byte [] llave2 = DatatypeConverter.parseBase64Binary(key);
PKCS8Key pkcs8 = new PKCS8Key( llave2, password.toCharArray()); //line 2
llave2 = pkcs8.getDecryptedBytes(); //line 3
certificado = DatatypeConverter.parseBase64Binary(cer);
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(llave2);
PrivateKey privateKey = kf.generatePrivate(ks);
X509EncodedKeySpec x = new X509EncodedKeySpec(certificado);
PublicKey publicKey = kf.generatePublic(x);
I get the following error in PublicKey publicKey = kf.generatePublic(x)
.
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(Unknown Source)
at java.security.KeyFactory.generatePublic(Unknown Source)
at vital.cancelaciones.GeneraXMLCancelacion.main(GeneraXMLCancelacion.java:118)
Caused by: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
at sun.security.x509.X509Key.decode(Unknown Source)
at sun.security.x509.X509Key.decode(Unknown Source)
at sun.security.rsa.RSAPublicKeyImpl.<init>(Unknown Source)
at sun.security.rsa.RSAKeyFactory.generatePublic(Unknown Source)
... 3 more
I guess I should do something similar with the public key as done with the private key in lines 2 and 3. Because the certificate is also encrypted. Any suggestions?
To test your scenario, I've created an RSA private key with
openssl
.Then I've converted this key to PKCS#8 DER format.
The manual of
openssl
refers to PKCS#8 and DER both as formats, so as far as I'm concerned the following happens:pkcs8
tellsopenssl
that I want to work with private keys in PKCS#8 format.-topk8
tells it that the private key I'm going to specify with-in
is not in PKCS#8 (otherwise it'll assume it is).-inform
and-in
specify that I want to convert the (PEM) private key to PKCS#8 (without-topk8
it'll try to convert a key already in PKCS#8 format to a standard key format).-outform
and-out
tells it I want a DER formatted key as output.-nocrypt
tells it that I don't want to encrypt the key.Then, with my RSA key (in standard format) I've created a certificate.
The certificate contains the public key corresponding to my private key.
After all of these, I've encoded both the private key and the certificate with Base64.
The following files were generated.
The main problem was that you had a certificate instead of a public key. The certificate contains the public key, but it cannot be loaded with
X509EncodedKeySpec(...)
, this is why theCertificateFactory
has to be used instead.(By the way here is a great article/tutorial on
openssl
and Java cryptography usage. I've got my info partly from there.)