我有一个方法可以将json请求发送到需要P12证书的REST API。 此方法将具有关联值的POJO用作参数。
首先,我将PKCS文件中的SSL证书导入到Java密钥库中。我遵循了本教程:https://jackstromberg.com/2013/05/importing-a-ssl-certificate-into-a-java-keystore-via-a-pkcs12-file/
创建密钥库文件:keytool -genkey -alias CERTIFICATE -keyalg RSA -keysize 2048 -keystore keystore 清空密钥库文件:keytool -delete -alias CERTIFICATE_MACSF -keystore密钥库 检查文件:keytool -v -list -keystore keystore.jks 导入PKCS文件:keytool -v -importkeystore -srckeystore CERTIFICATE.p12 -srcstoretype PKCS12 -destkeystore keystore -deststoretype JKS
阅读器是可以读取P12文件的类。 我创建一个SSLContext发送请求并构建标头:方法,内容类型,sslContext ... 所有值都在application.properties文件中定义,以便根据部署上下文对其进行修改。
公共DocumentDto sendRequest(DocumentDto documentDto)引发IOException,UnrecoverableKeyException,CertificateException,NoSuchAlgorithmException,KeyStoreException,KeyManagementException {
URL url = new URL(properties.getProperty("signature.api.url.full"));
Pkcs12Reader reader = new Pkcs12Reader(properties.getProperty("signature.api.certificate"), properties.getProperty("signature.api.passphrase"));
SSLContext sslContext =
reader.getSSLContext(
properties.getProperty("signature.api.certificate"),
properties.getProperty("signature.api.passphrase")
);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json; utf-8");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
urlConnection.setDoOutput(true);
System.out.println(urlConnection.toString());
ObjectMapper mapper = new ObjectMapper();
String jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(documentDto);
try(OutputStream os = urlConnection.getOutputStream()) {
byte[] input = jsonInString.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
try(BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8))) {
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
System.out.println(response.toString());
}
System.out.println(jsonInString);
return documentDto;
}
我的PkcsReader类检索实例:
public Pkcs12Reader(File certificate, String password) {
Objects.nonNull(certificate);
Objects.nonNull(password);
this.certificate = certificate;
this.password = password;
init();
}
private void init() {
try {
keyStore = KeyStore.getInstance("pkcs12");
keyStore.load(new FileInputStream(certificate), password.toCharArray());
} catch (Exception e) {
e.printStackTrace();
}
}
我的Pkcs类通过以下方式创建SSL上下文:
public SSLContext getSSLContext(String certPath, @NotNull String password)
throws IOException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException,
CertificateException, KeyManagementException {
KeyStore clientStore = KeyStore.getInstance("PKCS12");
clientStore.load(new FileInputStream(certificate), password.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientStore, password.toCharArray());
KeyManager[] kms = kmf.getKeyManagers();
KeyStore trustStore = KeyStore.getInstance("PKCS12");
trustStore.load(new FileInputStream(properties.getProperty("signature.api.jks")), password.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
TrustManager[] tms = tmf.getTrustManagers();
SSLContext sslContext = null;
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kms, tms, new SecureRandom());
return sslContext;
}
sun.net.www.protocol.https.DelegateHttpsURLConnection:https://sign-sandbox.xxxx.fr/signatures?orderRequestId=456464&mode=SYNC javax.net.ssl.SSLHandshakeException:PKIX路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到到请求目标的有效认证路径
在应用程序属性中: signature.api.certificate = C:/Java/jdk1.8.0_221/bin/CERTIFICATE.p12 signature.api.jks = C:/Java/jdk1.8.0_221/bin/keystore