以编程方式导入证书文件导致SOAP over HTTPS调用异常

时间:2017-08-30 07:45:22

标签: java spring ssl soap https

我有一个外部SOAP服务器,我必须通过https连接。我不想要的是使用keytool导入我从他们那里收到的两个.cer文件,因此我想以编程方式导入它们。

我收到的例外是sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

我用于导入证书的代码

@Bean
public WSClient wsClient(Jaxb2Marshaller marshaller) throws Exception {
    WSClient client = new WSClient();
    client.setDefaultUri(getClientUrl());
    client.setMarshaller(marshaller);
    client.setUnmarshaller(marshaller);

    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(null);
    createKeyStoreFromResource(ks, keyStore);

    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(ks, null);

    KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
    ts.load(null);
    createKeyStoreFromResource(ts, trustStore);

    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(ts);

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

    HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender();
    messageSender.setKeyManagers(keyManagerFactory.getKeyManagers());
    messageSender.setTrustManagers(trustManagerFactory.getTrustManagers());
    messageSender.setSslSocketFactory(sslContext.getSocketFactory());
    messageSender.setSslProtocol(sslContext.getProtocol());
    messageSender.setSslProvider(sslContext.getProvider().getName());

    messageSender.setHostnameVerifier((hostname, sslSession) -> true);

    client.setMessageSender(messageSender);
    return client;
}

private void createKeyStoreFromResource(KeyStore ks, Resource resource)
    throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, UnrecoverableKeyException {
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    BufferedInputStream bis = new BufferedInputStream(resource.getInputStream());

    while(bis.available() > 0) {
        Certificate certificate = cf.generateCertificate(bis);
        ks.setCertificateEntry("fiddler" + bis.available(), certificate);
    }
}

然后我public class WSClient extends WebServiceGatewaySupport使用getWebServiceTemplate().marshalSendAndReceive()

keyStoretrustStore是两个Resource个文件,位于类路径中,扩展名为.cer

keyStore .cer文件具有以下格式

Certificate:
Data:
    Version: 3 (0x2)
    Serial Number:
    .
    .
    .

trustStore .cer文件具有以下格式:

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

0 个答案:

没有答案