openssl der files importing into java keystore

本秂侑毒 提交于 2021-02-08 10:09:54

问题


I created a keypair with openssl and want them to import into the java-keystore:

1) openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out my_privatekey.pem
2) openssl rsa -pubout -outform DER -in my_privatekey.pem -out mypublic_key.der
3) openssl pkcs8 -topk8 -nocrypt -outform DER -in my_privatekey.pem -out my_privatekey.der

First, I create a private-key (in .pem-Format), then I create a public key and at the end I convert the private key into a format that can be used in java (pkcs8).

Now, I want to use those keys in a secure way in my java application, so I did some research and the solution seems to be by using the java-keystore.

However, if I am correct, you are not able to store the public key directly into the keystore, because you must create a certificate first:

convert your certificate in a DER format :

openssl x509 -outform der -in certificate.pem -out certificate.der

import into the keystore

keytool -import -alias your-alias -keystore cacerts -file certificate.der

This brings me now to my question. Is it possible to import the private and public key into the keystore without a certificate? I don't need a certificate, as I only want to store my keys securely, so they are password-protected.

If this is not possible, than you could create and sign your own certificate. However, a certificate can be expired, so after some time I have to always renew it or am I wrong?

I share this public key with a third-party (they need this key to verify the data which I signed with my private key) and I also get a public key from them, to encrypt some data. So I need to store 2 public keys at the end (my key and the public key which I receive).

How do I do that? Do I need to create 2 certificates as a hack, in order to be able to store them into the java-keystore?


回答1:


Aside: for just the keypair you don't need genpkey and then pkcs8 -topk8 -nocrypt -outform der; genpkey ... -outform der (without -$cipher) will create PKCS8-clear DER, the format JCE supports directly. For that matter even PKCS8-clear PEM can be handled easily enough by stripping the header and trailer lines and decoding the base64. This was not the case for the other commands needed in OpenSSL before 1.0.0 in 2010 (genrsa; gendsa; ecparam -genkey) which is part of the reason you will find lots of wrong advice about it all over the World Wide Copying.

The java.security.KeyStore API supports storing PrivateKey values only in conjunction with a certificate chain (which can be a single certificate). It also supports storing a lone certificate (to verify signatures from or encrypt data to someone else) but not a lone publickey. So yes you must create (or otherwise obtain) certificates.

The usual convention, if you don't want the security features of real certificate(s), is to create a 'self-signed' certificate -- one which follows the standard X.509v3 format, and contains the publickey, but is signed by its own key (specifically, the privatekey matching the publickey in the cert) rather than any CA's key. OpenSSL can do this several ways, such as the commonly recommended

openssl genpkey ... -out priv.pem 
openssl req -new -key priv.pem -x509 ... -out cert.pem

or you can combine key generation and cert creation with the simpler

openssl req -newkey rsa:2048 -keyout priv.pem -nodes -x509 ... -out cert.pem
# this doesn't support all the options of genpkey 
# but it does support the simple case you are using

It is also possible to split the 'req' and 'sign' steps:

openssl genpkey ... -out priv.pem
openssl req -new -key priv.pem ... -out csr.pem
openssl x509 -req -in csr.pem -signkey priv.pem ... -out cert.pem
# or
openssl req -newkey rsa:2048 -keyout priv.pem ... -out csr.pem
openssl x509 -req -in csr.pem -signkey priv.pem ... -out cert.pem

You can then write (simple) code to read in the privatekey and certificate and create a KeyStore entry -- and persist if you wish (which you presumably do). However keytool cannot do this directly. You can instead use openssl pkcs12 -export to combine the two OpenSSL files into a single PKCS12 file, which is password-encrypted and is usable directly as a keystore in currently supported Java. For really old Java you may need to convert the PKCS12 file to a JKS file using keytool -importkeystore -srcstoretype PKCS12 [-deststoretype JKS] ..., another piece of advice you will find widely copied.

Alternatively, unless you need the OpenSSL files for something else, keytool can do the whole job at once; just do keytool -genkeypair -keyalg rsa -keysize 2048 -keystore $file plus other options like -validity and -dname as desired, and it will generate the keypair and a self-signed cert for it and store the privatekey with the self-signed cert in a password-protected keystore file. (Through j8 defaults to JKS but you can specify otherwise; j9+ defaults to PKCS12.)

However, a certificate can be expired, so after some time I have to always renew it or am I wrong?

After some time, yes, but that time can be several thousand years. I suspect that both you and the third-party will be defunct by then, plus probably Java will no longer exist so the requirements imposed by Java APIs will no longer matter. Note that older versions of OpenSSL on 32-bit systems -- each rare today and the combination rarer -- sometimes were affected by the "Y2038" issue, and that is now only 18 years in the future -- many systems in use today will probably be obsolete by then, but not all. Java uses its own timestamp format and never had this problem.

CA-issued certificates usually have much shorter lifetimes, rarely more than 1-2 years and sometimes much less (as a notable example, 90 days for LetsEncrypt), but that's not inherent in the certificate spec and code.

Do I need to create 2 certificates as a hack, in order to be able to store them into the java-keystore?

Yes. To be exact, you certainly need to create a (dummy) cert for you own key. For the other party's key, it's easier if they create the (dummy) cert. You can't create a self-signed cert for them because you don't have their privatekey -- or at least you shouldn't. You can create a slightly more complicated structure where you create a dummy CA and use it to sign a cert for them, which you then import and use. I will expand if needed, but this is as I said more complicated, whereas many common tools are set up to allow them to do it very easily.




回答2:


The "keytool -importcert" command had no trouble reading the certificate in both PEM and DER formats.

keytool -importcert -file <openssl_crt.pem> -keystore <jks-file-name.jks> -storepass jkspass -alias <alias-name> -keypass <keypass>

keytool Importing Certificates in DER and PEM



来源:https://stackoverflow.com/questions/59351313/openssl-der-files-importing-into-java-keystore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!