利用Java实现mTLS调用

网友投稿 243 2022-11-25

利用Java实现mTLS调用

目录

本文将使用 java作为客户端 与受 mTLS 保护的服务交互。

为了对我们的 Java 客户端进行 ssl 配置,我们需要先设置一个 SSLContext。这简化了事情,因为 SSLContext 可用于各种 http 客户端。

由于我们有客户端公钥和私钥,我们需要将私钥从 PEM 格式转换为 DER。

openssl pkcs8 -topk8 -inform PEM -outform PEM -in /path/to/generated/client.key -out /path/to/generated/client.key.pkcs8 -nocrypt

下一步是将客户端密钥加载到 Java 代码中并创建一个 KeyManagerFactory:

String privateKeyPath = "/path/to/generated/client.key.pkcs8";

String publicKeyPath = "/path/to/generated/client.crt";

final byte[] publicData = Files.readAllBytes(Path.of(publicKeyPath));

final byte[] privateData = Files.readAllBytes(Path.of(privateKeyPath));

String privateString = new String(privateData, Charset.defaultCharset())

.replace("-----BEGIN PRIVATE KEY-----", "")

.replaceAll(System.lineSeparator(), "")

.replace("-----END PRIVATE KEY-----", ""

byte[] encoded = Base64.getDecoder().decode(privateString);

final CertificateFactory certificateFactory = CertificateFactory.getInstance(

"X.509");

byte[] encoded = Base64.getDecoder().decode(privateString);

final CertificateFactory certificateFactory = CertificateFactory.getInstance(

final Collection extends Certificate> chain = certificateFactory.generateCertificates(

new ByteArrayInputStream(publicData));

Key key = KeyFactory.getInstance("RSA"http://).generatePrivate(new PKCS8EncodedKeySpec(encoded));

KeyStore clientKeyStore = KeyStore.getInstance("jks");

final char[] pwdChars = "test".toCharArray();

clientKeyStore.load(null, null);

clientKeyStore.setKeyEntry("test", key, pwdChars, chain.toArray(new Certificate[0]));

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");

keyManagerFactory.init(clientKeyStore, pwdChars);

在上面的片段中

我们从文件中读取字节。

我们从公钥创建了一个证书链。

我们使用私钥创建了一个密钥实例。

使用链和密钥创建了一个密钥库

创建了一个 KeyManagerFactory

现在我们已经创建了一个 KeyManagerFactory 我们可以使用它来创建一个 SSLContext

由于使用自签名证书,我们需要使用接受它们的 TrustManager。在此示例中,信任管理器将接受服务器提供的所有证书。

TrustManager[] acceptAllTrustManager = {

new X509TrustManager() {

public X509Certificate[] getAcceptedIssuers() {

return new X509Certificate[0];

}

public void checkClientTrusted(

X509Certificate[] certs, String authType) {

}

public void checkServerTrusted(

X509Certificate[] certs, String authType) {

}

}

};

然后ssl上下文初始化。

SSLContext sslContext = SSLContext.gethttp://Instance("TLS");

sslContext.init(keyManagerFactory.getKeyManagers(), acceptAllTrustManager, new java.security.SecureRandom());

客户端代码:

HttpClient client = HttpClient.newBuilder()

http:// .sslContext(sslContext)

.build();

HttpRequest exactRequest = HttpRequest.newBuilder()

.uri(URI.create("https://127.0.0.1"))

.GET()

.build();

var exactResponse = client.sendAsync(exactRequest, HttpResponse.BodyHandlers.ofString())

.join();

System.out.println(exactResponse.statusCode());

我们将收到一个 404 代码,这意味着我们的请求成功进行了 mTLS 握手。

注意:如果服务器端是使用本地 Nginx 服务,我们需要禁用主机名验证。

final Properties props = System.getProperties();

props.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString());

在其他客户端中,这可能需要设置一个接受所有连接的 HostVerifier。

HostnameVerifier allHostsValid = new HostnameVerifier() {

public boolean verify(String hostname, SSLSession session) {

return true;

}

};

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:hadoop 分布式部署
下一篇:办公模式升级,服务式办公室强势来袭
相关文章

 发表评论

暂时没有评论,来抢沙发吧~