PKIX路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到有效的认证

时间:2019-10-23 08:30:30

标签: java ssl p12

我有一个方法可以将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

0 个答案:

没有答案