利用Java實(shí)現(xiàn)mTLS調(diào)用
本文將使用 Java作為客戶端 與受 mTLS 保護(hù)的服務(wù)交互。
為了對我們的 Java 客戶端進(jìn)行 ssl 配置,我們需要先設(shè)置一個(gè) SSLContext。這簡化了事情,因?yàn)?SSLContext 可用于各種 http 客戶端。
由于我們有客戶端公鑰和私鑰,我們需要將私鑰從 PEM 格式轉(zhuǎn)換為 DER。
openssl pkcs8 -topk8 -inform PEM -outform PEM -in /path/to/generated/client.key -out /path/to/generated/client.key.pkcs8 -nocrypt
下一步是將客戶端密鑰加載到 Java 代碼中并創(chuàng)建一個(gè) KeyManagerFactory:
String privateKeyPath = <font>"/path/to/generated/client.key.pkcs8"</font><font>;
String publicKeyPath = </font><font>"/path/to/generated/client.crt"</font><font>;
<b>final</b> byte[] publicData = Files.readAllBytes(Path.of(publicKeyPath));
<b>final</b> byte[] privateData = Files.readAllBytes(Path.of(privateKeyPath));
String privateString = <b>new</b> String(privateData, Charset.defaultCharset())
.replace(</font><font>"-----BEGIN PRIVATE KEY-----"</font><font>, </font><font>""</font><font>)
.replaceAll(System.lineSeparator(), </font><font>""</font><font>)
.replace(</font><font>"-----END PRIVATE KEY-----"</font><font>, </font><font>""</font><font>);
byte[] encoded = Base64.getDecoder().decode(privateString);
<b>final</b> CertificateFactory certificateFactory = CertificateFactory.getInstance(</font><font>"X.509"</font><font>);
<b>final</b> Collection<? <b>extends</b> Certificate> chain = certificateFactory.generateCertificates(
<b>new</b> ByteArrayInputStream(publicData));
Key key = KeyFactory.getInstance(</font><font>"RSA"</font><font>).generatePrivate(<b>new</b> PKCS8EncodedKeySpec(encoded));
KeyStore clientKeyStore = KeyStore.getInstance(</font><font>"jks"</font><font>);
<b>final</b> <b>char</b>[] pwdChars = </font><font>"test"</font><font>.toCharArray();
clientKeyStore.load(<b>null</b>, <b>null</b>);
clientKeyStore.setKeyEntry(</font><font>"test"</font><font>, key, pwdChars, chain.toArray(<b>new</b> Certificate[0]));
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(</font><font>"SunX509"</font><font>);
keyManagerFactory.init(clientKeyStore, pwdChars);
在上面的片段中
- 我們從文件中讀取字節(jié)。
- 我們從公鑰創(chuàng)建了一個(gè)證書鏈。
- 我們使用私鑰創(chuàng)建了一個(gè)密鑰實(shí)例。
- 使用鏈和密鑰創(chuàng)建了一個(gè)密鑰庫
- 創(chuàng)建了一個(gè)
KeyManagerFactory
現(xiàn)在我們已經(jīng)創(chuàng)建了一個(gè) KeyManagerFactory 我們可以使用它來創(chuàng)建一個(gè) SSLContext
由于使用自簽名證書,我們需要使用接受它們的 TrustManager。在此示例中,信任管理器將接受服務(wù)器提供的所有證書。
TrustManager[] acceptAllTrustManager = {
<b>new</b> X509TrustManager() {
<b>public</b> X509Certificate[] getAcceptedIssuers() {
<b>return</b> <b>new</b> X509Certificate[0];
}
<b>public</b> <b>void</b> checkClientTrusted(
X509Certificate[] certs, String authType) {
}
<b>public</b> <b>void</b> checkServerTrusted(
X509Certificate[] certs, String authType) {
}
}
};
然后ssl上下文初始化。
SSLContext sslContext = SSLContext.getInstance(<font>"TLS"</font><font>); sslContext.init(keyManagerFactory.getKeyManagers(), acceptAllTrustManager, <b>new</b> java.security.SecureRandom());
客戶端代碼:
HttpClient client = HttpClient.newBuilder()
.sslContext(sslContext)
.build();
HttpRequest exactRequest = HttpRequest.newBuilder()
.uri(URI.create(<font>"https://127.0.0.1"</font><font>))
.GET()
.build();
<b>var</b> exactResponse = client.sendAsync(exactRequest, HttpResponse.BodyHandlers.ofString())
.join();
System.out.println(exactResponse.statusCode());
我們將收到一個(gè) 404 代碼,這意味著我們的請求成功進(jìn)行了 mTLS 握手。
注意:如果服務(wù)器端是使用本地 Nginx 服務(wù),我們需要禁用主機(jī)名驗(yàn)證。
<b>final</b> Properties props = System.getProperties(); props.setProperty(<font>"jdk.internal.httpclient.disableHostnameVerification"</font><font>, Boolean.TRUE.toString());
在其他客戶端中,這可能需要設(shè)置一個(gè)接受所有連接的 HostVerifier。
HostnameVerifier allHostsValid = <b>new</b> HostnameVerifier() {
<b>public</b> <b>boolean</b> verify(String hostname, SSLSession session) {
<b>return</b> <b>true</b>;
}
};
到此這篇關(guān)于利用Java實(shí)現(xiàn)mTLS調(diào)用的文章就介紹到這了,更多相關(guān)Java實(shí)現(xiàn)mTLS調(diào)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mybatis/mybatis-plus模糊查詢語句特殊字符轉(zhuǎn)義攔截器的實(shí)現(xiàn)
在開發(fā)中,我們通常會遇到這樣的情況。用戶在錄入信息是錄入了‘%’,而在查詢時(shí)無法精確匹配‘%’。究其原因,‘%’是MySQL的關(guān)鍵字,如果我們想要精確匹配‘%’,那么需要對其進(jìn)行轉(zhuǎn)義,本文就詳細(xì)的介紹一下2021-11-11
Java調(diào)用第三方http接口的常用方式總結(jié)
這篇文章主要介紹了Java調(diào)用第三方http接口的常用方式總結(jié),具有很好的參考價(jià)值,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
Mybatis?連接mysql數(shù)據(jù)庫底層運(yùn)行的原理分析
這篇文章主要介紹了Mybatis?連接mysql數(shù)據(jù)庫底層運(yùn)行的原理分析,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
springboot + vue 實(shí)現(xiàn)遞歸生成多級菜單(實(shí)例代碼)
這篇文章主要介紹了springboot + vue 實(shí)現(xiàn)遞歸生成多級菜單,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12

