Я пытаюсь установить SSLContext для определенного вызова веб-службы. Цель состоит в том, чтобы программно указать сертификат клиента для вызова (на сервере с самозаверяющими сертификатами).
Я получил некоторые идеи от этого поста :
SSLContext sc = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance("JKS");
//...
ks.load(is, "passw".toCharArray());
kmf.init(ks, "passw".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
//...
tmf.init(ts);
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
com.ex.Ex service = new com.ex.Ex();
com.ex.ExService port = service.getDataServiceImplPort();
BindingProvider bp = (BindingProvider) port;
Map<String, Object> context = bp.getRequestContext();
context.put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sc.getSocketFactory());
text = port.callWS();
Мой код не должен зависеть от какой-либо конкретной JVM (не уверен, что com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory
не будет работать на определенных JVM).
Первый барьер - это то, что я получил эту ошибку:
Caused by: java.security.SignatureException: Signature does not match.
at sun.security.x509.X509CertImpl.verify(X509CertImpl.java:424)
at sun.security.provider.certpath.BasicChecker.verifySignature(BasicChecker.java:166)
at sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:147)
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
... 98 more
Что говорит мне о том, что хранилище доверенных сертификатов не используется.
Я также создал свой собственный фиктивный валидатор с такими же результатами. Похоже, что context.put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sc.getSocketFactory());
не установлено.
Я могу переопределить это, используя системные свойства, чтобы установить хранилище доверенных сертификатов глобально, но хранилище ключей не используется. Я мог бы также установить хранилище ключей, но это будет сделано глобально, так что это единственная точка программной установки сертификата клиента.