Skip to content

Instantly share code, notes, and snippets.

@softarts
Created July 14, 2022 13:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save softarts/f7b28f087ce0e6afd4ed0e3246f9ee29 to your computer and use it in GitHub Desktop.
Save softarts/f7b28f087ce0e6afd4ed0e3246f9ee29 to your computer and use it in GitHub Desktop.
mTLS: use Client certificate
import java.security.KeyFactory
import java.security.PrivateKey
import java.security.cert.Certificate
import java.security.cert.CertificateFactory
import java.security.interfaces.RSAPublicKey
import java.security.spec.PKCS8EncodededKeySpec
import java.security.spec.X509EncodededKeySpec
import java.util.Base64
import java.io.BufferedInputStream
import java.io.ByteArrayInputStream
fun genPrivateKey(resource: String): PrivateKey {
val factory = KeyFactory.getInstance("RSA")
return resource
.run(::load)
.run(::PKCS8EncodedKeySpec)
.run(factory::generatePrivate)
}
fun genPublicKey(resource: String): RSAPublicKey {
val factory = KeyFactory.getInstance("RSA")
return resource
.run(::load)
.run(::X509EncodedKeySpec)
.run(factory::generatePublic) as RSAPublicKey
}
fun genCertificate(resource: String): Certificate {
val factory = CertificateFactory.getInstance("X.509")
return resource
.run(::load)
.run(::ByteArrayInputStream)
.use(factory::genCertificate)
}
fun load(resource: String): ByteArray {
fun String.dropComments(): String {
return this
.replace("-----BEGIN CERTIFICATE-----", "")
.replace("-----END CERTIFICATE-----", "")
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replace("\\s+".toRegex(), "")
.replace("\n", "")
}
return BufferedInputStream(resource.byteInputStream())
.use { it.bufferedReader().readLines() }
.filter { it.isNotBlank() }
.joinToString(separator = "")
.dropComments()
.run(Base64.getDecoder()::decode)
}
fun getRestTemplate(
certpwd: String,
privateKey: String,
certificate: String
): RestTemplate {
val certPassword = certpwd.toCharArray()
val keystore: KeyStore = KeyStore.getInstance(KeyStore.getDefaultType())
keystore.load(null, null)
keystore.setKeyEntry(
"",
genPrivateKey(privateKey),
certPassword,
arrayOf(genCertificate(certificate))
)
val sslContext: SSLContext = SSLContextBuilder
.create()
.loadKeyMaterial(
keystore,
certPassword
)
.build()
val client: HttpClient = HttpClients.custom().setSSLContext(sslContext).build()
val requestFactory: ClientHttpRequestFactory = HttpComponentsClientHttpRequestFactory(client).apply {
setConnectionTimeout(5000)
setReadTimeout(5000)
}
return RestTemplateBuilder()
.requestFactory { requestFactory }.build()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment