В моем настольном приложении java есть класс, который соединяется с другой системой через соединение HTTPS, используя сертификат клиента. Частью этого соединения является SSLContext, который получает KeyManager [] и TrustManager [] для реализации пользовательского сертификата и хранилища trsut для получения подтверждения связи с удаленным сервером. Этот класс использует репозиторий Windows, чтобы получить список сертификатов, доступных на машине, чтобы пользователь мог выбрать правильный для подключения. Проблема в том, что я переносил это приложение на облачный веб-сервер (tomcat), и процедура получения сертификата совершенно иная. С tomcat я могу перенаправить пользователя на страницу https, которая запрашивает действительный сертификат, выданный ЦС. Как только пользователь заходит на эту страницу, в браузере появляется окно с сертификатами, доступными на машине, чтобы пользователь мог выбрать одну аутентификацию. Моя проблема сейчас заключается в том, чтобы создать этот SSLContext один раз, из аутентификации браузера я могу получить только сертификат x509, выбранный пользователем, но без закрытого ключа. Мой вопрос Я что-то пропустил, чтобы получить сертификат Закрытый ключ? Я знаю, что windows хранилище не разделяет закрытый ключ, но когда эта процедура вызывается из настольного приложения, по крайней мере, «резюме или заголовок» (RSAPrivateKey [размер = 2048 бит, тип = Exchange, контейнер = {## ######}) ключа, который все еще работает. Но через браузер я не могу получить эту информацию. Или есть другой способ создания KeyManager [] только с сертификатом x509 без предоставления закрытого ключа?
, вот фрагмент кода, который создает соединение с сервером.
// create the connection
SocketFactoryDinamico socketFactory = new SocketFactoryDinamico(X509certificate, PrivateKey);
socketFactory.setFileCacerts(getClass().getResourceAsStream("cacerts"));
KeyManager[] keyManagers = socketFactory.createKeyManagers();
TrustManager[] trustManagers = socketFactory.createTrustManagers();
SSLContext sslc = SSLContext.getInstance("TLS");
sslc.init(keyManagers, trustManagers, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslc.getSocketFactory());
String url = "https://someserver.com";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
и вот код, который получает сертификат x509 для. jsp ...
X509Certificate[] certs = (X509Certificate[])
request.getAttribute("javax.servlet.request.X509Certificate");
if (null != certs && certs.length > 0) {
X509Certificate cert = certs[0];
}
, а вот конфигурация сервера для запроса аутентификации сертификата
<Connector
clientAuth="true"
port="8443"
protocol="HTTP/1.1"
SSLEnabled="true"
scheme="https"
secure="true"
keystoreFile="C:/JavaWeb/tomcat"
keystoreType="JKS" keystorePass="pswd"
truststoreFile="C:/JavaWeb/myTrustStore"
truststoreType="JKS" truststorePass="changeit"
SSLVerifyCLient="require" SSLVerifyDepth="10" sslProtocol="TLS"
/>
Я пытался установить это соединение со стороны клиента с помощью javascript, однако я получаю эту ошибку: Доступ к XMLHttpRequest по адресу https://remoteserver.com 'origin' http://localhost 'было заблокировано политикой CORS: Ответ на запрос предварительной проверки не проходит проверку контроля доступа: в запрашиваемом ресурсе отсутствует заголовок «Access-Control-Allow-Origin».
Вот мой код:
var httpRequest = new XMLHttpRequest();
httpRequest.open("POST", "https://remoteserver.com");
httpRequest.setRequestHeader("Role-Type", "role");
httpRequest.onreadystatechange = function () {
if (this.readyState === 4) {
if (httpRequest.status === 200) {
console.log('Status:', this.status);
console.log('Headers:', this.getAllResponseHeaders());
console.log('Body:', this.responseText);
console.log(httpRequest);
} else {
console.log("Erro");
console.log(httpRequest);
}
}
};
httpRequest.send();