![](/img/trans.png)
[英]How do I use an SSL client certificate with jersey client in java
[英]How do I use client certificates in a client java application?
這是一個我花了很長時間才弄明白的話題。 零散的信息零散,必須將所有內容放在一起。 我希望通過這篇文章,我可以幫助其他人快速組裝一個可行的解決方案。
我有一個client-cert.pem
、 client-key.pem
和一個root.pem
文件,我需要在我的 Java 客戶端中使用它們來訪問遠程 REST API。
我如何將它們 package 放入信任庫並使用它們撥打 API 電話?
為了將您的證書加載到您的應用程序中,您需要將它們打包到一個信任庫中。
創建信任庫
給定 3 個文件:
client-cert.pem
client-key.pem
root.pem
在終端中運行以下命令。 將PASSWORD
替換為您想要的密碼。
將您的客戶端密鑰和證書打包到密鑰庫中。 這將創建一個 PKCS12 密鑰庫文件。
openssl pkcs12 -export \ -inkey client-key.pem -in client-cert.pem \ -out client.pfx -passout pass:PASSWORD \ -name qlikClient
將密鑰庫添加到您的信任庫。 如果目的地不存在,它將創建一個信任庫。 這將創建一個PKCS12
信任庫文件。 默認情況下,它會創建專有格式的JKS
文件。 通過指定-deststoretype PKCS12
,您將創建一個行業標准格式的文件。
keytool -importkeystore \ -destkeystore truststore.pfx -deststoretype PKCS12 -deststorepass PASSWORD \ -srckeystore client.pfx -srcstorepass PASSWORD -srcstoretype PKCS12 \ -alias qlikClient
將您的根 CA 添加到信任庫
keytool -importcert \ -keystore truststore.pfx -storepass PASSWORD \ -file root.pem -noprompt \ -alias qlikServerCACert
請注意,在上述命令中,我們對密鑰庫和信任庫使用相同的PASSWORD
。 您也可以使用不同的密碼。 另請注意,您必須為添加到信任庫的每個項目指定一個別名。
如果您希望信任庫信任系統中可用的所有 cacerts,請將-trustcacerts
選項添加到步驟 2 或 3。
您可以使用以下命令列出信任庫的內容
keytool -list -keystore truststore.pfx -storepass PASSWORD
在您的應用程序中使用信任庫
擁有信任庫后,您需要將其加載到您的應用程序中。 假設您有一個常量KEYSTORE_PATH
保存您的信任庫的路徑和keyStorePass
保存密碼,將信任庫文件讀入KeyStore
private KeyStore readStore() {
try (InputStream keyStoreStream = new FileInputStream(KEYSTORE_PATH)) {
KeyStore keyStore = KeyStore.getInstance("PKCS12"); // or "JKS"
keyStore.load(keyStoreStream, keyStorePass.toCharArray());
return keyStore;
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
創建自定義SSLContext
和自定義HttpClient
,
final KeyStore truststore = readStore();
final SSLContext sslContext;
try {
sslContext = SSLContexts.custom()
.loadTrustMaterial(truststore, new TrustAllStrategy())
.loadKeyMaterial(truststore, keyStorePass.toCharArray(), (aliases, socket) -> "qlikClient")
.build();
} catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException | UnrecoverableKeyException e) {
throw new RuntimeException("Failed to read keystore", e);
}
final CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();
您現在可以使用此HttpClient
向您的 API 發出請求。
HttpResponse response = httpClient.execute(new HttpGet("https://sense-gcp-central1eu.net:4242/qrs/app/full"));
或者,如果您使用的是OpenUnirest/unirest-java庫,則可以將 Unirest 配置為使用您的自定義HttpClient
Unirest.config().httpClient(httpClient);
HttpResponse<JsonNode> response = Unirest.get("https://sense-gcp-central1eu.net:4242/qrs/app/full").asJson();
參考
我知道這是一個老問題,但我發現你的問題有問題。
您的客戶端使用信任庫來列出它可以信任的遠程服務器。
如果您擁有並想使用的證書/密鑰是為您自己的 java 客戶端准備的,您應該將它們包含在您的密鑰庫中,而不是信任庫中。
這是您的客戶端將使用的存儲,以防遠程服務器要求您的客戶端對自己進行身份驗證。
除了已經給出的答案之外,如果您使用 spring 引導和 resttemplate 作為 http 客戶端實現,您可以在應用程序屬性中使用通過這樣做創建的密鑰庫:
server:
ssl:
enabled: true
key-alias: <<app-client-alias>>
key-store: <<path_to_your_keystore>>
key-store-password: <<PASSWORD>>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.