How to Configure TLS/SSL With PEM Files

This tutorial will explain to you how to easily configure your favorite http client for java, kotlin, and scala with tls/ssl while using PEM files instead of the traditional jks or p12 files. I will use the traditional http client of the jdk, HttpURLConnection, as an example for this tutorial. But you can find here 30+ other client examples: Example HTTP Client configurations.

We will send an https request to https://client.badssl.com/ where the client needs to authenticate itself with its own certificates. This is also known as mutual authentication. The server will require the client to identify itself and both parties need to trust each other. Without identification, you will receive a 400 Bad Request as a response. If it passes you will receive a status code 200.

The client identity as badssl-identity.pem:

Plain Text
 




x
67


 
1
Bag Attributes
2
    localKeyID: 41 C3 6C 33 C7 E3 36 DD EA 4A 1F C0 B7 23 B8 E6 9C DC D8 0F
3
subject=C = US, ST = California, L = San Francisco, O = BadSSL, CN = BadSSL Client Certificate
4
 
          
5
issuer=C = US, ST = California, L = San Francisco, O = BadSSL, CN = BadSSL Client Root Certificate Authority
6
 
          
7
-----BEGIN CERTIFICATE-----
8
MIIEqDCCApCgAwIBAgIUK5Ns4y2CzosB/ZoFlaxjZqoBTIIwDQYJKoZIhvcNAQEL
9
BQAwfjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
10
DVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDExMC8GA1UEAwwoQmFkU1NM
11
IENsaWVudCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xOTExMjcwMDE5
12
NTdaFw0yMTExMjYwMDE5NTdaMG8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
13
Zm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQKDAZCYWRTU0wx
14
IjAgBgNVBAMMGUJhZFNTTCBDbGllbnQgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3
15
DQEBAQUAA4IBDwAwggEKAoIBAQDHN18R6x5Oz+u6SOXLoxIscz5GHR6cDcCLgyPa
16
x2XfXHdJs+h6fTy61WGM+aXEhR2SIwbj5997s34m0MsbvkJrFmn0LHK1fuTLCihE
17
EmxGdCGZA9xrwxFYAkEjP7D8v7cAWRMipYF/JP7VU7xNUo+QSkZ0sOi9k6bNkABK
18
L3+yP6PqAzsBoKIN5lN/YRLrppsDmk6nrRDo4R3CD+8JQl9quEoOmL22Pc/qpOjL
19
1jgOIFSE5y3gwbzDlfCYoAL5V+by1vu0yJShTTK8oo5wvphcFfEHaQ9w5jFg2htd
20
q99UER3BKuNDuL+zejqGQZCWb0Xsk8S5WBuX8l3Brrg5giqNAgMBAAGjLTArMAkG
21
A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgeAMAsGA1UdDwQEAwIF4DANBgkqhkiG
22
9w0BAQsFAAOCAgEAZBauLzFSOijkDadcippr9C6laHebb0oRS54xAV70E9k5GxfR
23
/E2EMuQ8X+miRUMXxKquffcDsSxzo2ac0flw94hDx3B6vJIYvsQx9Lzo95Im0DdT
24
DkHFXhTlv2kjQwFVnEsWYwyGpHMTjanvNkO7sBP9p1bN1qTE3QAeyMZNKWJk5xPl
25
U298ERar6tl3Z2Cl8mO6yLhrq4ba6iPGw08SENxzuAJW+n8r0rq7EU+bMg5spgT1
26
CxExzG8Bb0f98ZXMklpYFogkcuH4OUOFyRodotrotm3iRbuvZNk0Zz7N5n1oLTPl
27
bGPMwBcqaGXvK62NlaRkwjnbkPM4MYvREM0bbAgZD2GHyANBTso8bdWvhLvmoSjs
28
FSqJUJp17AZ0x/ELWZd69v2zKW9UdPmw0evyVR19elh/7dmtF6wbewc4N4jxQnTq
29
IItuhIWKWB9edgJz65uZ9ubQWjXoa+9CuWcV/1KxuKCbLHdZXiboLrKm4S1WmMYW
30
d0sJm95H9mJzcLyhLF7iX2kK6K9ug1y02YCVXBC9WGZc2x6GMS7lDkXSkJFy3EWh
31
CmfxkmFGwOgwKt3Jd1pF9ftcSEMhu4WcMgxi9vZr9OdkJLxmk033sVKI/hnkPaHw
32
g0Y2YBH5v0xmi8sYU7weOcwynkjZARpUltBUQ0pWCF5uJsEB8uE8PPDD3c4=
33
-----END CERTIFICATE-----
34
Bag Attributes
35
    localKeyID: 41 C3 6C 33 C7 E3 36 DD EA 4A 1F C0 B7 23 B8 E6 9C DC D8 0F
36
Key Attributes: <No Attributes>
37
-----BEGIN ENCRYPTED PRIVATE KEY-----
38
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIy3Fposf+2ccCAggA
39
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECFOXAIo35o51BIIEyLsnLgbzRpsI
40
qsephRcXVWt4lXgWF1uHD+mFL9JMqC8K1ESV/SUbIAaINziWlyBjkkCduPMOHbER
41
6zUP60ixisPi8jkihkV1bvJvWeHXsQjjTAYXtwVX2s9T5D+IYK4CF8lOe5eiG1Pb
42
UV3oD78zcOeM+aGRjSDKneSx4bUFiv33bziBDAtnk6Ts5lg6x5HtM0YQBCycqpMH
43
I7jpafH+TZSVqdyAdL8Jc5bByAQk8SWvEFXxPP5RS9YfeOd3WDvzJQaHSw8otf6h
44
lpimxbXhOrI84r1YZwDy/3QaYdnKUPBYSZniBje2G/g0Su5ZanCvvhhhhQlN18QO
45
AjQGEZKlfuxi8cq/EZWqFrnui6KSiutCmcnMyJ8mcS2dDGVsr3GVPpnyzpokSTY1
46
q2o/b9hqV/9ETzVYeNyO4L5MVIuxTxM8hNj4gkmFMkv8diDS6TmKO2kOasZAuUYO
47
Eq+diZKj1CZg+qejf3u+93fycyk9b1rrsL6iG24QMdHgTsn/ZyX85ZUHFXba+qWn
48
G2rZsseBR4UcKxjUWO7ElH6oD8WUP/St7/88q5XFV1AuC0CGc6L+a4je3EbKjhK8
49
9fFXgSXbYMPIOQ1y0ShHt3YNpRKOCoV2mwZE1FtVIGGlUlu30kY/Ov93sXGYUvtm
50
/b+GMQrc7tZq7l5qNoI253zfhgX2gWOmU092JAPoDvzDz0QP2vVjB4BqlNJKuOBP
51
IKBckCQbj4mKWy27LVCMZfylU08k5KfUyvEHxwmD5aj+LClZzGS1GkeQcG80RYrl
52
DGeLkQXC+li/cSxmKhQ2RPfZ4xR1ImzQdFQJsm9dcHq5arwU5W/N2t3c/0mORKIp
53
j5mJCm8IVlVP05Rnxmz2wtL+VnUt7M9BQjeUDs155X4Rqp8j24bCtonp8fCnejjw
54
fBu83zTjo+a8eHTWsyjfJyDnTSNq1HgyWDGhkTSWLW7+UVrG8bUuuGI+C0HtRuPp
55
49XHrcHXBSufM+t8YHf+DebZ/7dJNnL1DqVOGaFh5fyYJNtMAd1IyT9NkCOq6d22
56
p1bXFQF5IWrrNJ1FMRT6GzkAUYHd86jGJUuNm1vPqAAF/8eoow2PK75Qu8G+hIjY
57
k03mUAZzQn12tHidMAVS08frmYBMwmIEwWK+AlOGA8jJoyfJ06dRDN8qcIQ3RQSP
58
uH/chBsmO/0HPKQYE19fAqqxLQqzaU1yqq6UStTyDCvsuZdJnAwQEi43Wzt3EkNk
59
50i5fZp6me1x80LARRZFDv5YjEb+hbK4BjKPAoRHL1BbYM5uhGV2F08Y6qqVBhK0
60
uG1ykwxhnNkS49/7dVwoayBKHHvCbeoOw+E3qmvKfc3jpI93osYGCzFPP0+dKpZN
61
szfrkI35gVnPSdh0SCSBMLcqkeFMyAeKH4fL13KckU0swe2WSYk/JZlay5Ba+HRM
62
5zd/j0SAGYYOjvBMrhbLU5g9q2llanv7i8zEHKcb3LzeEaD7XoK5OEHnth9c5Lyx
63
HD2IxzftLN5J1pXHvioi+KTNJNS4z2k35AQCyNez+g8gFmuhsssYD9dUjEjhbNra
64
C+D/XlHAZDESksribfm4nTuOOQiyVzdKJ8Xmxsy9Ckjcq5gn5jNvsv96eP2QC5ok
65
FHeRMpMdlCLXw78iQ6HjJw==
66
-----END ENCRYPTED PRIVATE KEY-----
67
 
          



And the trusted certificates as badssl-certificate.pem:

Plain Text
 




xxxxxxxxxx
1
39


1
-----BEGIN CERTIFICATE-----
2
MIIGqDCCBZCgAwIBAgIQCvBs2jemC2QTQvCh6x1Z/TANBgkqhkiG9w0BAQsFADBN
3
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
4
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMjAwMzIzMDAwMDAwWhcN
5
MjIwNTE3MTIwMDAwWjBuMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p
6
YTEVMBMGA1UEBxMMV2FsbnV0IENyZWVrMRwwGgYDVQQKExNMdWNhcyBHYXJyb24g
7
VG9ycmVzMRUwEwYDVQQDDAwqLmJhZHNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUA
8
A4IBDwAwggEKAoIBAQDCBOz4jO4EwrPYUNVwWMyTGOtcqGhJsCK1+ZWesSssdj5s
9
wEtgTEzqsrTAD4C2sPlyyYYC+VxBXRMrf3HES7zplC5QN6ZnHGGM9kFCxUbTFocn
10
n3TrCp0RUiYhc2yETHlV5NFr6AY9SBVSrbMo26r/bv9glUp3aznxJNExtt1NwMT8
11
U7ltQq21fP6u9RXSM0jnInHHwhR6bCjqN0rf6my1crR+WqIW3GmxV0TbChKr3sMP
12
R3RcQSLhmvkbk+atIgYpLrG6SRwMJ56j+4v3QHIArJII2YxXhFOBBcvm/mtUmEAn
13
hccQu3Nw72kYQQdFVXz5ZD89LMOpfOuTGkyG0cqFAgMBAAGjggNhMIIDXTAfBgNV
14
HSMEGDAWgBQPgGEcgjFh1S8o541GOLQs4cbZ4jAdBgNVHQ4EFgQUne7Be4ELOkdp
15
cRh9ETeTvKUbP/swIwYDVR0RBBwwGoIMKi5iYWRzc2wuY29tggpiYWRzc2wuY29t
16
MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
17
awYDVR0fBGQwYjAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Et
18
c2hhMi1nNi5jcmwwL6AtoCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2Nh
19
LXNoYTItZzYuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUH
20
AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQIDMHwGCCsG
21
AQUFBwEBBHAwbjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t
22
MEYGCCsGAQUFBzAChjpodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl
23
cnRTSEEyU2VjdXJlU2VydmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwggF+BgorBgEE
24
AdZ5AgQCBIIBbgSCAWoBaAB2ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaO
25
HtGFAAABcQhGXioAAAQDAEcwRQIgDfWVBXEuUZC2YP4Si3AQDidHC4U9e5XTGyG7
26
SFNDlRkCIQCzikrA1nf7boAdhvaGu2Vkct3VaI+0y8p3gmonU5d9DwB2ACJFRQdZ
27
VSRWlj+hL/H3bYbgIyZjrcBLf13Gg1xu4g8CAAABcQhGXlsAAAQDAEcwRQIhAMWi
28
Vsi2vYdxRCRsu/DMmCyhY0iJPKHE2c6ejPycIbgqAiAs3kSSS0NiUFiHBw7QaQ/s
29
GO+/lNYvjExlzVUWJbgNLwB2AFGjsPX9AXmcVm24N3iPDKR6zBsny/eeiEKaDf7U
30
iwXlAAABcQhGXnoAAAQDAEcwRQIgKsntiBqt8Au8DAABFkxISELhP3U/wb5lb76p
31
vfenWL0CIQDr2kLhCWP/QUNxXqGmvr1GaG9EuokTOLEnGPhGv1cMkDANBgkqhkiG
32
9w0BAQsFAAOCAQEA0RGxlwy3Tl0lhrUAn2mIi8LcZ9nBUyfAcCXCtYyCdEbjIP64
33
xgX6pzTt0WJoxzlT+MiK6fc0hECZXqpkTNVTARYtGkJoljlTK2vAdHZ0SOpm9OT4
34
RLfjGnImY0hiFbZ/LtsvS2Zg7cVJecqnrZe/za/nbDdljnnrll7C8O5naQuKr4te
35
uice3e8a4TtviFwS/wdDnJ3RrE83b1IljILbU5SV0X1NajyYkUWS7AnOmrFUUByz
36
MwdGrM6kt0lfJy/gvGVsgIKZocHdedPeECqAtq7FAJYanOsjNN9RbBOGhbwq0/FP
37
CC01zojqS10nGowxzOiqyB4m6wytmzf0QwjpMw==
38
-----END CERTIFICATE-----
39
 
          



The following code snippet will use these two files and generate the required objects and with that, you can execute an https request with those ssl materials. See below for the example usage:

Java
 




x


1
var keyManager = PemUtils.loadIdentityMaterial("badssl-identity.pem", "badssl.com".toCharArray());
2
var trustManager = PemUtils.loadTrustMaterial("badssl-certificate.pem");
3
 
          
4
SSLFactory sslFactory = SSLFactory.builder()
5
        .withIdentityMaterial(keyManager)
6
        .withTrustMaterial(trustManager)
7
        .build();
8
 
          
9
HttpsURLConnection connection = (HttpsURLConnection) new URL("https://client.badssl.com/").openConnection();
10
connection.setSSLSocketFactory(sslFactory.getSslSocketFactory());
11
connection.setHostnameVerifier(sslFactory.getHostnameVerifier());
12
connection.setRequestMethod("GET");
13
 
          
14
int statusCode = connection.getResponseCode();
15
System.out.println(statusCode);



The above code snippet is available here: SSLFactoryIT

See here for all other use cases: GitHub - SSLContext Kickstart

And find here an example for other http clients: Example HTTP Client configurations

 

 

 

 

Top