Исключение Certificate_Unknown от Java SSL-сервераJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Исключение Certificate_Unknown от Java SSL-сервера

Сообщение Anonymous »

Я создаю небольшое настольное приложение, которое будет подключаться к моему серверу и передавать некоторые зашифрованные данные через SSLServerSocket для сервера и обычный сокет для клиента. Для этого я использую созданные мной хранилища ключей, которые содержат сертификаты Сервера. Клиентская часть работает нормально, сообщает о подключении к серверу и никогда не выдает ошибок. Он даже не завершает соединение сокета при сбое на стороне сервера. Сам сервер регистрирует подключение клиента без проблем, но как только я пытаюсь инициализировать объект BufferedWriter, происходит сбой со следующей трассировкой стека:

Код: Выделить всё

javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
at sun.security.ssl.Alert.createSSLException(Alert.java:131)
at sun.security.ssl.Alert.createSSLException(Alert.java:117)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:318)
at sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
at sun.security.ssl.TransportContext.dispatch(TransportContext.java:185)
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:152)
at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1397)
at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1305)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:818)
at sun.security.ssl.SSLSocketImpl.access$200(SSLSocketImpl.java:73)
at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:909)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at ClientHandler.(ClientHandler.java:27)
at KillSwitchServer.run(KillSwitchServer.java:55)
at KillSwitchServer.main(KillSwitchServer.java:38)
В строке 27 ClientHandler (класс, существующий исключительно на стороне сервера) происходит инициализация BufferedWriter.
Сейчас я использую JDK 1.8, хотя я также пробовал перейти на версию 21 и получил те же результаты. Судя по тому, что я уже нашел об этой ошибке, похоже, что она почти всегда возникает исключительно на стороне клиента, поэтому я здесь немного растерян. Я несколько раз проверил и убедился, что мои хранилища ключей верны и что все сертификаты активны и не имеют срока действия. При подключении к моему серверу через Google браузер подтверждает, что сертификат обновлен, а веб-страница защищена HTTPS. На всякий случай я также добавил сертификаты Сервера в файл cacerts используемого мной JDK, хотя, поскольку программная среда использует собственное хранилище доверенных сертификатов, это ни на что не должно повлиять, и никаких изменений замечено не было.
Вот важные фрагменты файлов KillSwitchServer и ClientHandler, которые обрабатывают инициализацию SSLServerSocket и подключение клиента.

Код: Выделить всё

public class KillSwitchServer {

private static final int PORT_NUMBER = 2048;
private static final String KEYSTORE_FILE = "Server_Keystore.jks";
private static final String KEYSTORE_PASSWORD = "Server_Keystore_password";

public static void main(String[] args) throws IOException{
System.setProperty("javax.net.ssl.keyStore", KEYSTORE_FILE);
System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);

SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();

SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(PORT_NUMBER);

new KillSwitchServer(serverSocket).run();
}

private SSLServerSocket serverSocket;

public KillSwitchServer(SSLServerSocket serverSocket){
this.serverSocket = serverSocket;
}

public void run(){
try{
while(!serverSocket.isClosed()){
Socket clientSocket = serverSocket.accept();

System.out.println("Client connected.");

ClientHandler clientHandler = new ClientHandler(clientSocket);

new Thread(clientHandler).start();
}
}catch(IOException e){
closeServerSocket();
}
}

// ****** CLIENT HANDLER - Normally a separate file *********
public class ClientHandler implements Runnable {

public static ClientHandler currentClient;

private Socket clientSocket;

private BufferedReader clientReader;
private BufferedWriter clientWriter;

private String encodedKey;
private String passwordHash;

public ClientHandler(Socket clientSocket) {
try{
this.clientSocket = clientSocket;
this.clientReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

//Crash either occurs here
this.clientWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

//Or here
this.encodedKey = clientReader.readLine();
this.passwordHash = clientReader.readLine();

if(authenticateClient()){
currentClient = this;

System.out.println("Password correct.");

messageClient("Connection established.");
}else{
messageClient("Invalid password. Please try again.");

System.out.println("Password incorrect.");

closeConnection(clientSocket, clientReader, clientWriter);
}

}catch (IOException e) {
closeConnection(clientSocket, clientReader, clientWriter);
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException |
BadPaddingException e) {
throw new RuntimeException(e);
}
}

@Override
public void run() {
String clientMessage;

while(clientSocket.isConnected()) {
try{
clientMessage = clientReader.readLine();
processClientMessage(clientMessage);
}catch(IOException e){
closeConnection(clientSocket, clientReader, clientWriter);
break;
}
}
}

public void messageClient(String message){
try{
clientWriter.write(message);
clientWriter.newLine();
clientWriter.flush();
}catch(IOException e){
closeConnection(clientSocket, clientReader, clientWriter);
}
}
Любая помощь по этому вопросу будет очень признательна, спасибо!
РЕДАКТИРОВАТЬ: проблема оказалась в несовпадении пар ключей в доверительных отношениях клиент/сервер. магазины! Всем, у кого возникнет эта проблема в будущем, все, что мне нужно было сделать, чтобы решить эту проблему, — это сначала сгенерировать пару ключей в хранилище доверенных сертификатов моего сервера, используя сертификат сервера. Затем я экспортировал эту пару ключей и импортировал ее в хранилище доверенных сертификатов моего клиента. Таким образом, оба хранилища доверенных сертификатов содержали сертификат(ы) Сервера и пару ключей, созданную с использованием этого сертификата. Это заставило систему работать. Если это поможет, на протяжении всего этого процесса я также использовал инструмент с графическим интерфейсом под названием Keystore Explorer, который значительно облегчил работу с хранилищами доверенных сертификатов.

Подробнее здесь: https://stackoverflow.com/questions/785 ... ssl-server
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»