I get a InvalidKeyException: invalid key format when creating a java.security.PublicKey from a PEM file generated by openssl ec -pubout ....
The same code works for RSA keys.
What am I doing wrong?
The public key reads:
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAG0FCGgyhUeJYUXeXoiKOU4GiyTORZ
U9+OpadxpVWqPbNoSNcfK7Ea13eWOKXlUe22v4Clce3t5nrCEBkwqhhe/g==
-----END PUBLIC KEY-----
EC key generation with OpenSSL:
openssl ecparam -genkey -out private_key.pem -outform PEM -name prime256v1
openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -out private_key.der -nocrypt
openssl ec -in private_key.pem -inform PEM -out public_key.pem -outform PEM -pubout
(I already tried different settings for conv_form and param_enc)
Java code:
KeyFactory kf = KeyFactory.getInstance("EC");
byte[] privEncoded = ... // read from private_key.der file
PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(privEncoded);
PrivateKey privKey = kf.generatePrivate(privSpec);
byte[] pubEncoded = .... // read from public_key.pem file
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubEncoded);
PublicKey pubKey = kf.generatePublic(pubSpec); // <-- InvalidKeyException
Edit: Contrary to what I said above, reading the RSA public key now fails too when trying it with a newly generated PEM. Also, encrypting and then decrypting fails. Stripping the BEGIN and END line from the PEM and converting Base64 to byte, as suggested by GregS, solved it!
The so-called "PEM" format is not supported by Java. You must either save the data in openssl's "DER" format or strip out the first and last lines and decode the base64 in your Java program. See javax.xml.bind.DataTypeConverter.parseBase64Binary to go from base64 to bytes.
Related
I have some data which has been signed using something like the following:
openssl rsautl -sign -in file -inkey PrivateKey.pem -out sig
The signed data can then be recovered using the following:
openssl rsautl -pubin -inkey PublicKey.pem -verify -in sig -out file
I've converted the public key into a Java PublicKey object and looked at using that with the Signature class in java.security, but that doesn't appear to have a method that allows recovering the original signed data.
Is there a way to recover the signed data using Java?
As suggested in the comment by dave_thompson_085, the following can be used to recover the data:
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] extractedBytes = cipher.doFinal(sig);
I want to get privatekey from BKS store by program but i found it is difference between my parse and the pem file.
Any body know why is that?
Here is my code:
KeyStore testkeyStore = KeyStore.getInstance("bks");
testkeyStore.load(inputstream, keystorepass);
PrivateKey key = (PrivateKey)testkeyStore .getKey("xxxxx",keypassword);
byte[] bas = key.getEncoded();
bas = Base64.encode(bas, Base64.DEFAULT);
String keys = new String(bas);
Log.d("XXX","keys " + keys);
Here is how i transfer bks to pem:
keytool -importkeystore -srckeystore xxx.bks -srcstoretype BKS -destkeystore xx.p12 -deststoretype PKCS12 -provider org.bouncycastle.jce.provider.BouncyCastleProvider
openssl pkcs12 -in xxx.p12 -out xxx.pem
I found answer after i traced code of openssl project.
The private key was encrypted, here is the code:
https://github.com/openssl/openssl/blob/master/apps/pkcs12.c
I'm trying to Der encode a public key, and use it with an external service.
When I get the encoded org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey and send it to the external service, it responds with "ECDSA certificates with unnamed curves are unsupported". (I'm calling publicKey.getEncoding() to get the encoded key)
publicKey.getFormat();
// "X.509"
publicKey.getAlgorithm();
// "ECDH"
publicKey.getQ().curve.getClass().name;
// "org.bouncycastle.math.ec.custom.sec.SecP256R1Curve"
I'm not really sure how to debug from here. I tried saving the raw encoded bytes
to a file and inspecting the cert with openssl without success:
> openssl x509 -in test.der -inform der -text -noout
unable to load certificate
62375:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64.30.2/src/crypto/asn1/tasn_dec.c:1344:
62375:error:0D06C03A:asn1 encoding routines:ASN1_D2I_EX_PRIMITIVE:nested asn1 error:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64.30.2/src/crypto/asn1/tasn_dec.c:848:
62375:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64.30.2/src/crypto/asn1/tasn_dec.c:768:Field=serialNumber, Type=X509_CINF
62375:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64.30.2/src/crypto/asn1/tasn_dec.c:768:Field=cert_info, Type=X509
Any help would be greatly appreciated!
Here's the solution I came up with:
KeyFactory keyFactory = KeyFactory.getInstance("EC");
X509EncodedKeySpec keySpec = keyFactory.getKeySpec(publicKey, X509EncodedKeySpec.class);
return keySpec.getEncoded();
I try to encrypt some data in matlab using a public key I created with openssl
I created the keys using:
openssl genrsa -des3 -out private.pem 1024
openssl rsa -in private.pem -pubout -outform DER -out public.der
I encrypt my data using this matlab code (with Java libraries):
import java.security.spec.RSAPublicKeySpec
import javax.crypto.Cipher;
import java.security.KeyFactory
import java.math.BigInteger
fid = fopen('public.der');
a = fread(fid);
key = java.security.spec.X509EncodedKeySpec(a);
kf = KeyFactory.getInstance('RSA');
KEY = kf.generatePublic(key);
cipher = Cipher.getInstance('RSA/ECB/PKCS1Padding');
cipher.init(Cipher.ENCRYPT_MODE, KEY)
plaintextBytes = [24];
ciphertext = cipher.doFinal(plaintextBytes)' ;
fid2 = fopen('msg.txt','w');
fwrite(fid2,ciphertext);
fclose(fid2);
I try to decrypt it using:
openssl rsautl -decrypt -inkey private.pem -in msg.txt -keyform PEM -pkcs
Then I get this error:
RSA operation error
80305:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.40.2/src/crypto/rsa/rsa_pk1.c:267:
80305:error:04065072:rsa routines:RSA_EAY_PRIVATE_DECRYPT:padding check failed:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.40.2/src/crypto/rsa/rsa_eay.c:614:
Most of the time for such "RSA_padding_check_PKCS1_type_2 error ..." - you tends to see this with
(1) Encoding errors: instead of decrypting binary data, decrypting is done on (maybe) Base64 encoded data.
(2) Mismatched key pair or key itself: Public key does not matched to the Private key for decryption.
http://hustoknow.blogspot.ca/2013/01/rsa-block-type-is-not-02-error.html
Maybe we can make sure the pair is not mismatch (2) too before saying the cipher load is not correct (1). Like below in ref to https://www.sslshopper.com/ssl-converter.html
Convert PEM to DER: openssl x509 -outform der -in certificate.pem -out certificate.der
or if the cert is already in "der" format, can also be turn into "pem"
e.g. Convert DER to PEM: openssl x509 -inform der -in certificate.cer -out certificate.pem
Convert PEM to PFX: openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt
or if there is only "pfx" then can get "pem"
e.g. Convert PFX to PEM: openssl pkcs12 -in certificate.pfx -out certificate.cer -nodes
After making sure we have the "pem", we can try the encrypt and decrypt as stated in
http://openssl.6102.n7.nabble.com/unable-to-decrypt-using-using-private-key-td15204.html
e.g. 1) openssl enc -base64 -d -in -out where was created and it had binary contents.
e.g. 2) openssl rsautl -decrypt -inkey -out -pkcs
but in this case, consider trying to use -raw instead of -pkcs to decrypt data with server private
key
I am working on IdP-initiated SAML response for Salesforce and need your help.
I was working with the code and found that I need a .pem (private) key.
KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("alias", new KeyStore.PasswordProtection(password));
PrivateKey pk = pkEntry.getPrivateKey();
The PEM key will be used to sign my response signature. Where can I get a .pem key?
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj ‘/C=US/ST=CA/L=San Mateo/CN=www.appirio.com’ -keyout key-mycompanyrsa.pem -out cert-mycompanyrsa.pem
More info:
http://blog.jeffdouglas.com/2010/07/06/using-rsa-sha1-with-salesforce-crypto-class/