<code>
public class OkhttpClientTest2 {
private static final Logger log = LoggerFactory.getLogger(OkhttpClientTest2.class);
public static void main(String[] args) throws UnrecoverableKeyException, KeyManagementException,
KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient().newBuilder();
okHttpClientBuilder.connectTimeout(10,TimeUnit.SECONDS);
okHttpClientBuilder.readTimeout(20,TimeUnit.SECONDS);
setSslSocketFactory(okHttpClientBuilder);
okHttpClientBuilder.followRedirects(false);
okHttpClientBuilder.followSslRedirects(false);
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(okhttp3.logging.HttpLoggingInterceptor.Level.BASIC);
okHttpClientBuilder.addInterceptor(logging);
Set<String> hostNames = new HashSet<>();
hostNames.add("localhost");
okHttpClientBuilder.hostnameVerifier(
new OverrideHostnamesVerifier(hostNames, OkHostnameVerifier.INSTANCE));
OkHttpClient okHTTPClient = okHttpClientBuilder.build();
Request httpRequest = configureRequest();
Response responseHttp = okHTTPClient.newCall(httpRequest).execute();
int statusCode = responseHttp.code();
ResponseBody responseBody = responseHttp.body();
System.out.println("statusCode :: "+statusCode);
String text = IOUtils.toString(responseBody.byteStream(), StandardCharsets.UTF_8.name());
System.out.println("Response Body :: "+text);
}
private static Request configureRequest() throws MalformedURLException {
Request.Builder requestBuilder = new Request.Builder();
URL url = new URL("https://localhost:9098/student/getInfo");
requestBuilder = requestBuilder.url(url).get();
requestBuilder.addHeader("Accept", "application/json");
return requestBuilder.build();
}
private static void setSslSocketFactory(OkHttpClient.Builder okHttpClientBuilder) throws IOException, KeyStoreException, CertificateException,
NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
final KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
// initialize the KeyManager array to null and we will overwrite later
// if a keystore is loaded
KeyManager[] keyManagers = null;
keyManagers = getKeyManagers(keyManagerFactory);
loadTruststore(trustManagerFactory);
final X509TrustManager x509TrustManager;
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers[0] != null) {
x509TrustManager = (X509TrustManager) trustManagers[0];
} else {
throw new IllegalStateException("List of trust managers is null");
}
for (int i=0; i<keyManagers.length; i++) {
if (keyManagers[i] instanceof X509KeyManager) {
keyManagers[i]=new AliasSelectorKeyManager((X509KeyManager)keyManagers[i], "MyServer5");
}
}
SSLContext sslContext = SSLContext.getInstance("TLSv1");
sslContext.init(keyManagers, trustManagerFactory.getTrustManagers(), null);
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
okHttpClientBuilder.sslSocketFactory(sslSocketFactory, x509TrustManager);
}
private static void loadTruststore(TrustManagerFactory trustManagerFactory)
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
final String trustStoreLocation = "C:/FAST/certificate/clienttruststore.jks";
final String trustStorePass = "changeit";
final String trustStoreType = "JKS";
KeyStore truststore = KeyStore.getInstance(trustStoreType);
try (FileInputStream stream = new FileInputStream(trustStoreLocation)) {
truststore.load(stream, trustStorePass.toCharArray());
}
trustManagerFactory.init(truststore);
}
private static KeyManager[] getKeyManagers(KeyManagerFactory keyManagerFactory)
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException,
UnrecoverableKeyException {
KeyManager[] keyManagers;
final String keystoreLocation = "C:/FAST/certificate/clientkeystore.jks";
final String keystorePass = "changeit";
final String keystoreType = "JKS";
// prepare the keystore
final KeyStore keyStore = KeyStore.getInstance(keystoreType);
try (FileInputStream keyStoreStream = new FileInputStream(keystoreLocation))
{
keyStore.load(keyStoreStream, keystorePass.toCharArray());
}
//Certificate cert = keyStore.getCertificate("MyServer");
//System.out.println("cert::"+cert);
keyManagerFactory.init(keyStore, keystorePass.toCharArray());
keyManagers = keyManagerFactory.getKeyManagers();
return keyManagers;
}
}
</code>
<code>
public class AliasSelectorKeyManager extends X509ExtendedKeyManager{
private X509KeyManager sourceKeyManager=null;
private String alias;
public AliasSelectorKeyManager(X509KeyManager keyManager, String alias){
super();
this.sourceKeyManager=keyManager;
this.alias = alias;
}
@Override
public String chooseClientAlias(String[] keyType, Principal[] issuers,Socket socket){
boolean aliasFound=false;
//Get all aliases from the key manager. If any matches with the managed alias,
//then return it.
//If the alias has not been found, return null (and let the API to handle it,
//causing the handshake to fail).
for (int i=0; i<keyType.length && !aliasFound; i++) {
String[] validAliases=sourceKeyManager.getClientAliases(keyType[i], issuers);
if (validAliases!=null) {
for (int j=0; j<validAliases.length && !aliasFound; j++) {
if (validAliases[j].equals(alias)) aliasFound=true;
}
}
}
if (aliasFound) {
return alias;
}
else return null;
}
@Override
public String chooseServerAlias(String keyType, Principal[] issuers,Socket socket){
return sourceKeyManager.chooseServerAlias(keyType, issuers, socket);
}
@Override
public X509Certificate[] getCertificateChain(String alias){
return sourceKeyManager.getCertificateChain(alias);
}
@Override
public String[] getClientAliases(String keyType, Principal[] issuers){
return sourceKeyManager.getClientAliases(keyType, issuers);
}
@Override
public PrivateKey getPrivateKey(String alias){
return sourceKeyManager.getPrivateKey(alias);
}
@Override
public String[] getServerAliases(String keyType, Principal[] issuers){
return sourceKeyManager.getServerAliases(keyType, issuers);
}
@Override
public String chooseEngineServerAlias(String keyType, Principal[] issuers,
SSLEngine engine) {
if (alias!=null) {
return alias;
}
return super.chooseEngineServerAlias(keyType, issuers, engine);
}
}
</code>
У меня есть хранилище ключей с 3 псевдонимами сертификата
пример
Мой сервер1
Myserver2
Myserver3
OKHttpClient не вызывает методы переопределения X509ExtendedKeyManager для выбора правильного сертификата на основе псевдонима.
Как заставить вышеуказанный код работать, т.е. выбрать правильный сертификат на основе псевдонима?
Есть ли класс, который мне нужно переопределить, чтобы выбрать правильный псевдоним в OkHTTP. Я искал в Google и не смог найти ответа.