使用 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"); final Collection<? extends Certificate> chain = certificateFactory.generateCertificates( new ByteArrayInputStream(publicData)); Key key = KeyFactory.getInstance("RSA").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.getInstance("TLS"); sslContext.init(keyManagerFactory.getKeyManagers(), acceptAllTrustManager, new java.security.SecureRandom()); |
客戶端程式碼:
HttpClient client = HttpClient.newBuilder() .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; } }; |
相關文章
- Java使用HttpClient實現遠端服務呼叫JavaHTTPclient
- Java實現非同步呼叫Java非同步
- 手把手教你用 Go 實現一個 mTLSGoTLS
- 教你如何用 Java 實現非同步呼叫Java非同步
- 基於OpenTelemetry實現Java微服務呼叫鏈跟蹤Java微服務
- 使用併發工具實現 RPC 呼叫流量控制RPC
- 使用LangChain4J實現Agent與Tool呼叫LangChain
- 實現呼叫API介面API
- 呼叫鏈系列(2):輕呼叫鏈實現
- nacos實現Java和.NetCore的服務註冊和呼叫JavaNetCore
- C++庫封裝JNI介面——實現java呼叫c++C++封裝Java
- 使用Java實現WebSocket通訊JavaWeb
- 如何使用java實現Open AddressingJava
- 自己寫了個Java RMI(遠端方法呼叫)的實現案例Java
- Java 中使用 Failsafe 實現容錯JavaAI
- 使用emscripten實現js直接呼叫C程式碼(emscripten的初探)JSC程式
- 使用resilience4j-retry實現函式呼叫重試函式
- 如何使用Java呼叫商品詳情APIJavaAPI
- Spring Boot使用@Async實現非同步呼叫:使用Future以及定義超時Spring Boot非同步
- 實現通過COM元件方式實現java呼叫C#寫的DLL檔案的完整demo元件JavaC#
- Java大作業:AI千戀萬花(呼叫api實現)附專案)JavaAIAPI
- Java 專案中使用 Resilience4j 實現客戶端 API 呼叫的限速/節流機制Java客戶端API
- Eureka實現微服務的呼叫微服務
- Android JNI實現Java與C/C++互相呼叫,以及so庫的生成和呼叫(JNI方式呼叫美圖秀秀so)AndroidJavaC++
- Java中使用FlatBuffer實現序列化Java
- Java中使用FlatBuffers實現序列化Java
- Java使用Netty實現簡單的RPCJavaNettyRPC
- 使用Java加密與解密實現步驟Java加密解密
- Laravel 如何實現既能靜態呼叫,又能動態呼叫Laravel
- 在Java中使用panama FFI呼叫Rust庫JavaRust
- Spring Boot使用@Async實現非同步呼叫:自定義執行緒池Spring Boot非同步執行緒
- C#使用委託實現函式回撥,方法呼叫攔截C#函式
- Eureka-實現微服務的呼叫微服務
- Android Studio 呼叫Camera實現拍照功能Android
- CompletableFuture中實現多個 REST 呼叫REST
- netty 實現簡單的rpc呼叫NettyRPC
- 介面呼叫超時的實現原理
- Hanlp中使用純JAVA實現CRF分詞HanLPJavaCRF分詞