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:
Bag Attributes 
              localKeyID: 41 C3 6C 33 C7 E3 36 DD EA 4A 1F C0 B7 23 B8 E6 9C DC D8 0F 
          subject=C = US, ST = California, L = San Francisco, O = BadSSL, CN = BadSSL Client Certificate 
          issuer=C = US, ST = California, L = San Francisco, O = BadSSL, CN = BadSSL Client Root Certificate Authority 
          -----BEGIN CERTIFICATE----- 
          MIIEqDCCApCgAwIBAgIUK5Ns4y2CzosB/ZoFlaxjZqoBTIIwDQYJKoZIhvcNAQEL 
          BQAwfjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM 
          DVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDExMC8GA1UEAwwoQmFkU1NM 
          IENsaWVudCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xOTExMjcwMDE5 
          NTdaFw0yMTExMjYwMDE5NTdaMG8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp 
          Zm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQKDAZCYWRTU0wx 
          IjAgBgNVBAMMGUJhZFNTTCBDbGllbnQgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3 
          DQEBAQUAA4IBDwAwggEKAoIBAQDHN18R6x5Oz+u6SOXLoxIscz5GHR6cDcCLgyPa 
          x2XfXHdJs+h6fTy61WGM+aXEhR2SIwbj5997s34m0MsbvkJrFmn0LHK1fuTLCihE 
          EmxGdCGZA9xrwxFYAkEjP7D8v7cAWRMipYF/JP7VU7xNUo+QSkZ0sOi9k6bNkABK 
          L3+yP6PqAzsBoKIN5lN/YRLrppsDmk6nrRDo4R3CD+8JQl9quEoOmL22Pc/qpOjL 
          1jgOIFSE5y3gwbzDlfCYoAL5V+by1vu0yJShTTK8oo5wvphcFfEHaQ9w5jFg2htd 
          q99UER3BKuNDuL+zejqGQZCWb0Xsk8S5WBuX8l3Brrg5giqNAgMBAAGjLTArMAkG 
          A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgeAMAsGA1UdDwQEAwIF4DANBgkqhkiG 
          9w0BAQsFAAOCAgEAZBauLzFSOijkDadcippr9C6laHebb0oRS54xAV70E9k5GxfR 
          /E2EMuQ8X+miRUMXxKquffcDsSxzo2ac0flw94hDx3B6vJIYvsQx9Lzo95Im0DdT 
          DkHFXhTlv2kjQwFVnEsWYwyGpHMTjanvNkO7sBP9p1bN1qTE3QAeyMZNKWJk5xPl 
          U298ERar6tl3Z2Cl8mO6yLhrq4ba6iPGw08SENxzuAJW+n8r0rq7EU+bMg5spgT1 
          CxExzG8Bb0f98ZXMklpYFogkcuH4OUOFyRodotrotm3iRbuvZNk0Zz7N5n1oLTPl 
          bGPMwBcqaGXvK62NlaRkwjnbkPM4MYvREM0bbAgZD2GHyANBTso8bdWvhLvmoSjs 
          FSqJUJp17AZ0x/ELWZd69v2zKW9UdPmw0evyVR19elh/7dmtF6wbewc4N4jxQnTq 
          IItuhIWKWB9edgJz65uZ9ubQWjXoa+9CuWcV/1KxuKCbLHdZXiboLrKm4S1WmMYW 
          d0sJm95H9mJzcLyhLF7iX2kK6K9ug1y02YCVXBC9WGZc2x6GMS7lDkXSkJFy3EWh 
          CmfxkmFGwOgwKt3Jd1pF9ftcSEMhu4WcMgxi9vZr9OdkJLxmk033sVKI/hnkPaHw 
          g0Y2YBH5v0xmi8sYU7weOcwynkjZARpUltBUQ0pWCF5uJsEB8uE8PPDD3c4= 
          -----END CERTIFICATE----- 
          Bag Attributes 
              localKeyID: 41 C3 6C 33 C7 E3 36 DD EA 4A 1F C0 B7 23 B8 E6 9C DC D8 0F 
          Key Attributes: <No Attributes> 
          -----BEGIN ENCRYPTED PRIVATE KEY----- 
          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 
          FHeRMpMdlCLXw78iQ6HjJw== 
          -----END ENCRYPTED PRIVATE KEY----- 
          And the trusted certificates as badssl-certificate.pem:
xxxxxxxxxx 
          -----BEGIN CERTIFICATE----- 
          MIIGqDCCBZCgAwIBAgIQCvBs2jemC2QTQvCh6x1Z/TANBgkqhkiG9w0BAQsFADBN 
          MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E 
          aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMjAwMzIzMDAwMDAwWhcN 
          MjIwNTE3MTIwMDAwWjBuMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p 
          YTEVMBMGA1UEBxMMV2FsbnV0IENyZWVrMRwwGgYDVQQKExNMdWNhcyBHYXJyb24g 
          VG9ycmVzMRUwEwYDVQQDDAwqLmJhZHNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUA 
          A4IBDwAwggEKAoIBAQDCBOz4jO4EwrPYUNVwWMyTGOtcqGhJsCK1+ZWesSssdj5s 
          wEtgTEzqsrTAD4C2sPlyyYYC+VxBXRMrf3HES7zplC5QN6ZnHGGM9kFCxUbTFocn 
          n3TrCp0RUiYhc2yETHlV5NFr6AY9SBVSrbMo26r/bv9glUp3aznxJNExtt1NwMT8 
          U7ltQq21fP6u9RXSM0jnInHHwhR6bCjqN0rf6my1crR+WqIW3GmxV0TbChKr3sMP 
          R3RcQSLhmvkbk+atIgYpLrG6SRwMJ56j+4v3QHIArJII2YxXhFOBBcvm/mtUmEAn 
          hccQu3Nw72kYQQdFVXz5ZD89LMOpfOuTGkyG0cqFAgMBAAGjggNhMIIDXTAfBgNV 
          HSMEGDAWgBQPgGEcgjFh1S8o541GOLQs4cbZ4jAdBgNVHQ4EFgQUne7Be4ELOkdp 
          cRh9ETeTvKUbP/swIwYDVR0RBBwwGoIMKi5iYWRzc2wuY29tggpiYWRzc2wuY29t 
          MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw 
          awYDVR0fBGQwYjAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Et 
          c2hhMi1nNi5jcmwwL6AtoCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2Nh 
          LXNoYTItZzYuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUH 
          AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQIDMHwGCCsG 
          AQUFBwEBBHAwbjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t 
          MEYGCCsGAQUFBzAChjpodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl 
          cnRTSEEyU2VjdXJlU2VydmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwggF+BgorBgEE 
          AdZ5AgQCBIIBbgSCAWoBaAB2ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaO 
          HtGFAAABcQhGXioAAAQDAEcwRQIgDfWVBXEuUZC2YP4Si3AQDidHC4U9e5XTGyG7 
          SFNDlRkCIQCzikrA1nf7boAdhvaGu2Vkct3VaI+0y8p3gmonU5d9DwB2ACJFRQdZ 
          VSRWlj+hL/H3bYbgIyZjrcBLf13Gg1xu4g8CAAABcQhGXlsAAAQDAEcwRQIhAMWi 
          Vsi2vYdxRCRsu/DMmCyhY0iJPKHE2c6ejPycIbgqAiAs3kSSS0NiUFiHBw7QaQ/s 
          GO+/lNYvjExlzVUWJbgNLwB2AFGjsPX9AXmcVm24N3iPDKR6zBsny/eeiEKaDf7U 
          iwXlAAABcQhGXnoAAAQDAEcwRQIgKsntiBqt8Au8DAABFkxISELhP3U/wb5lb76p 
          vfenWL0CIQDr2kLhCWP/QUNxXqGmvr1GaG9EuokTOLEnGPhGv1cMkDANBgkqhkiG 
          9w0BAQsFAAOCAQEA0RGxlwy3Tl0lhrUAn2mIi8LcZ9nBUyfAcCXCtYyCdEbjIP64 
          xgX6pzTt0WJoxzlT+MiK6fc0hECZXqpkTNVTARYtGkJoljlTK2vAdHZ0SOpm9OT4 
          RLfjGnImY0hiFbZ/LtsvS2Zg7cVJecqnrZe/za/nbDdljnnrll7C8O5naQuKr4te 
          uice3e8a4TtviFwS/wdDnJ3RrE83b1IljILbU5SV0X1NajyYkUWS7AnOmrFUUByz 
          MwdGrM6kt0lfJy/gvGVsgIKZocHdedPeECqAtq7FAJYanOsjNN9RbBOGhbwq0/FP 
          CC01zojqS10nGowxzOiqyB4m6wytmzf0QwjpMw== 
          -----END CERTIFICATE----- 
          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:
x
var keyManager = PemUtils.loadIdentityMaterial("badssl-identity.pem", "badssl.com".toCharArray()); 
          var trustManager = PemUtils.loadTrustMaterial("badssl-certificate.pem"); 
          SSLFactory sslFactory = SSLFactory.builder() 
                  .withIdentityMaterial(keyManager) 
                  .withTrustMaterial(trustManager) 
                  .build(); 
          HttpsURLConnection connection = (HttpsURLConnection) new URL("https://client.badssl.com/").openConnection(); 
          connection.setSSLSocketFactory(sslFactory.getSslSocketFactory()); 
          connection.setHostnameVerifier(sslFactory.getHostnameVerifier()); 
          connection.setRequestMethod("GET"); 
          int statusCode = connection.getResponseCode(); 
          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

