我有一些发出 HTTP 请求的 Python 代码:
import requests
response = requests.get(
url,
cert = tuple(clientCertPath, pkeyPath), // paths to crt.pem and pkey.pem
verify = serverCertPath // path to server-ca.crt file
)
我想使用 ktor 将其重写为 Kotlin。这是我到目前为止所想到的:
val serverCert = serverCertPath.inputStream().use {
CertificateFactory.getInstance("X.509").generateCertificate(it) as X509Certificate
}
val keyStore = KeyStore.getInstance(...).apply {
load(null, null)
setCertificateEntry("serverCert", serverCert)
}
val trustManagerFactory = ... // init with keystore
val sslContext = SSLContext.getInstance("TLS") // and init with above config
val client = HttpClient(Java) {
engine {
config {
sslContext(sslContext)
}
}
}
// So far so good. This server certificate config seems to work and cover the 'verify' parameter. Now for the other cert.
val clientCert = CertificateFactory.getInstance("X.509").let {
clientCertPath.inputStream().use { stream -> it.generateCertificate(stream) as X509Certificate }
}
client.request(url) {
this.method = HttpMethod.Get
// how to supply client cert?
}
现在我陷入困境了。如何将客户端证书应用于请求?客户端级配置或请求级配置对我来说都可以。另外,我还没用过
pkeyPath
。我在哪里可以做到这一点?
有几种方法可以加载 pem 文件并从中创建 sslcontext。然而,对于传统的 java 来说,它有点冗长。如果您只想使用它而不需要额外的库,您可以尝试以下 stacker flow 主题 如何从 PEM 证书和密钥构建 SSLSocketFactory 而无需转换为密钥库?
或者你可以尝试我的库,它有点不那么冗长。您需要做的是加载您的 pen 文件并创建一个密钥管理器和信任管理器,您可以使用它们来创建 sslcontext。 Ktor 将能够使用这个对象。示例代码片段如下:
var keyManager = PemUtils.loadIdentityMaterial("certificate-chain.pem", "private-key.pem");
var trustManager = PemUtils.loadTrustMaterial("some-trusted-certificate.pem");
var sslFactory = SSLFactory.builder()
.withIdentityMaterial(keyManager)
.withTrustMaterial(trustManager)
.build();
var sslContext = sslFactory.getSslContext();
您可以将包含以下代码片段的库添加到您的项目中:
implementation("io.github.hakky54:sslcontext-kickstart:8.1.5")