Issues while migrating from OpenSSL 1.1.x to OpenSSL 3.1.1(creating .crt and .key files from a .p12 file)

1.2k Views Asked by At

I am creating self signed certificates for my Java Web Application. My application uses Apache Tomcat and Apache HTTPD proxy. I was using OPENSSL 1.1.1 and Java keytool till now for self signed certificates and it works perfectly fine. But now I need to move to OpenSSL 3.1.1 and am facing issues.

Step1: Create a keystore

keytool -genkeypair -alias keystore -keyalg RSA -keystore C:\SSL\PVIStore -keysize 2048

Step2: Import keystore generated in step#1 to a .p12 file

keytool -importkeystore -srckeystore C:\SSL\PVIStore -destkeystore C:\SSL\PVIStore.p12 -deststoretype PKCS12

Step3: Get .crt file from file generated in step#2 using openssl 3.1.1

openssl pkcs12 -in C:\PVIStore.p12 -nokeys -out C:\SSL\PVIStore.crt

Step4: Get .key file from the file generated in step#2 using openssl 3.1.1

openssl pkcs12 -in C:\SSL\PVIStore.p12 -nocerts -nodes -out C:\SSL\PVIStore.key

Step #3 and Step #4 work perfectly fine in openssl 1.1.x but when using with openssl 3.1.1 I am getting below error:-

Error outputting keys and certificates 94210000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto\evp\evp_fetch.c:341:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()

Note: I got a workaround to work for me by following another stackoverflow discussion, but I do not want to use the legacy switch to move ahead.

Any help is greatly appreciated.

2

There are 2 best solutions below

2
Matt Caswell On

Add the -legacy option to your OpenSSL pkcs12 command line.

See the man page which says this:

When encountering problems loading legacy PKCS#12 files that involve, for example, RC2-40-CBC, try using the -legacy option and, if needed, the -provider-path option.

https://www.openssl.org/docs/man3.1/man1/openssl-pkcs12.html

1
dave_thompson_085 On
  1. You can change your OpenSSL config file to load the legacy provider (in addition to the default one); this can be either the compiled-in file (depends on your system/environment but typically something like /etc/pki/openssl.conf or /usr/share/openssl.conf) or your own file set with an env var, see How to enable the OpenSSL 3.0 legacy provider Github Actions? .

    This still uses the legacy algorithm just not the -legacy option; I don't know if this satisfies your objection.

  2. If you want to stop using the old algorithm, use keytool from Java 8u301 11.0.12 or 16 up -- or manually modify the settings in java.security or set the equivalent system properties in 12 through 15 but those are all end-of-life now so that's probably a bad idea.

  3. Or going further afield, you can use OpenSSL to create your key and self-signed cert in the first place, not Java keytool. With OpenSSL 3.0.0 up, openssl pkcs12 -export will use only new encryption (PBES2/AES) which both OpenSSL 3.x and 1.x will read, however some versions of Java (and specifically some updates of Java 8) cannot read these files either because of PBES2 in general, PBES2 with AES, or PBMAC-SHA256; there are numerous Qs about these here and on security.SX superuser serverfault.

    There are several variations with openssl commandline: you can create the key separately with genrsa or genpkey, then a CSR with req -new, then a cert with x509 -req -signkey. You can combine the first step into the second using -newkey [-keyout] [-nodes], and the third step into the second using -x509 (i.e. an option not a subcommand). And lots of Qs about all of them.

Also FYI in Java 9 up the default keystore type is PKCS12, so if -genkey[pair] creates a new keystore (i.e. doesn't update an existing JKS) that keystore is already PKCS12 and doesn't need to be converted with -importkeystore. In Java 8 you can change the default type to PKCS12 in java.security if you want.