Код: Выделить всё
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)
Сейчас я использую 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
Мобильная версия