Converted to p12 but truststore is PrivateCertEntry not CertEntry (Spring Boot)

My domain is: footeware.ca

I ran this command: sudo certbot certonly -a standalone -d footeware.ca

It produced this output:
Requesting a certificate for footeware.ca
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/footeware.ca/fullchain.pem
Key is saved at: /etc/letsencrypt/live/footeware.ca/privkey.pem
This certificate expires on 2022-04-03.
These files will be updated when the certificate renews.

My web server is (include version): Embedded Tomcat in Spring Boot 2.6.1 jar not sure the version.

The operating system my web server runs on is (include version): Ubuntu 20.10

My hosting provider, if applicable, is: local 'server' computer

I can login to a root shell on my machine (yes or no, or I don't know): yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel): no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): certbot 1.22.0

I converted the generated artifacts to p12 via:
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat -CAfile chain.pem -caname root

I moved the p12 to my development machine into my eclipse project's resources folder.
When I start the application (and its server) and debug thru it finds the truststore but states it's not an instanceof sun.security.pkcs12.PKCS12KeyStore.CertEntry but rather a sun.security.pkcs12.PKCS12KeyStore$PrivateKeyEntry and so it fails with:

java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

What have I done wrong?

I should have added this from keytool -list

Alias name: tomcat
Creation date: Jan. 3, 2022
Entry type: PrivateKeyEntry
Certificate chain length: 3
Certificate[1]:
Owner: CN=footeware.ca
Issuer: CN=R3, O=Let's Encrypt, C=US

Try rebuilding the p12 file without (one or both of these):

1 Like

No luck. I tried with and without each of them and without both of them but the p12 still lists as PrivateKeyEntry.

Please show the chain.pem file used.

1 Like
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----

I really don't know much about PKCS#12 but I wonder if the -inkey privkey.pem is doing something you don't want (if the software you're using doesn't expect the private key to be included in the resulting file). It seems that this is asking openssl to read the private key corresponding to the certificate and so I imagine it would presumably want to include that private key in the output file as well.

1 Like

I'm a total noob with certs in general and I've been following blogs and posts to set this up. They all seem to agree in that exact conversion of the pems to p12 using openssl though. Unless there's something wrong with the generated pems, and I definitely doubt that, I suspect I'm doing something wrong on the Spring Boot side. Would it be poor etiquette to cross-post on Stack Overflow? They have a dedicated Spring Boot tag that seems to deliver pretty good.

I feel like Java and PKCS#12 stuff is one area where this forum's expertise is unfortunately fairly thin, so I don't think there would be anything at all wrong with trying a different forum where people might have more experience with that.

On this forum, when users are using Tomcat, people have often suggested not using Tomcat's HTTPS support directly, and instead creating a reverse proxy with something like Caddy (that has built-in Let's Encrypt support) that then proxies to a TCP port on localhost where Tomcat is listening. That can be a very quick and convenient solution, but I also understand if people want to get things working with a Tomcat-only approach. But it's just not something that most people on this forum have had that much experience with. :frowning:

2 Likes

Thanks, for those following along at home:

1 Like

I think perhaps your trust store does not know about the Let's Encrypt root (ISRG Root X1) and it needs to be imported java - Client Authentication Tomcat - trustAnchors parameter must be non-empty - Stack Overflow

2 Likes

Try removing the last cert from the files:
chain.pem
fullchain.pem
and retry the p12.

Then we shall see if:

1 Like

Didn't seem to make any difference:

InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

Then it seems that:

1 Like

I did:

sudo update-ca-certificates -f
sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure

...and used my original keystore.p12 (seems there was nothing wrong with it).
The solution was to change my application.properties' values to:

server.ssl.trust-store=file:/etc/ssl/certs/java/cacerts
server.ssl.trust-store-password=changeit
server.ssl.trust-store-type=JKS

I had been setting those properties to the keystore.p12 thinking they were one and the same (noob).
I deployed and started the appication jar, set my router to forward 443 to my server@8443 (instead of 80 to 8090 as it was) and I'm in with a happy https indicator!

Now I just have to fix the broken css that upgrading bootstrap seems to have caused. Pain that the cert prevents me from using localhost now as it only supports footeware.ca.
Any ideas there?

1 Like

Great, so potentially your default config for the trusts store was not pointing to an updated cacerts locations.

To work on localhost but emulate connecting via the real domain you can add the fully qualified (domain) name to your hosts file for development pointing to 127.0.0.1 (or any local machine IP), then browse to your website normally using the 'real' domain that matches the cert. This works on Windows as well as linux and macos. You just need to remember and remove it later!

2 Likes

Perfect! Thanks for everything.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.