Исключение в потоке "main" java.io.IOException: неверный формат хранилища ключей в sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:658)
У меня есть файл mycert.crt, и я хочу подключиться к серверу, используя мой код Java. Я получаю заголовок исключения. Мой код выглядит следующим образом:
final MqttConnectOptions connnOpt = new MqttConnectOptions();
connnOpt.setCleanSession(false);
connnOpt.setKeepAliveInterval(2000);
connnOpt.setUserName(user.getUsername());
connnOpt.setPassword(user.getSDPApiDriver().getToken().toCharArray());
connnOpt.setConnectionTimeout(20000);
String sslCert="/mycert.crt";
System.setProperty("javax.net.ssl.trustStore", sslCert);
System.setProperty("javax.net.ssl.trustStorePassword", "expectBrilliance");
System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
KeyStore ks = KeyStore.getInstance("JKS");
InputStream jksInputStream = this.getClass().getResourceAsStream(sslCert);
ks.load(jksInputStream, "expectBrilliance".toCharArray()); //thrown exception
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "expectBrilliance".toCharArray());
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
SSLContext sc = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = tmf.getTrustManagers();
sc.init(kmf.getKeyManagers(), trustManagers, null);
SSLSocketFactory ssf = sc.getSocketFactory();
connnOpt.setSocketFactory(ssf);
String locationTopic = "abcd/efgh/" + dongleId + "/events";
final MqttClient client = new MqttClient(clientDevice.getBrokerUrl(), dongleId,null);
client.connect(connnOpt);
System.out.println("client status : " + client.isConnected());
в моем java.security есть keystore.type=jks. Используя этот файл mycert.crt, я могу войти на мой сервер hivemq с помощью mqtt-spy. Имя пользователя: abcd Пароль:wxyz Вкладка "Безопасность" Режим TLS: сертификат CA Протокол: TLSv1 Файл сертификата CA: mycert.zip Я просматриваю разные сайты, но сейчас получаю ответ.
1 ответ
Эта проблема решается путем преобразования файла.crt в файл.jks с помощью следующей команды: $keytool -importcert -file Desktop\mycert\mycert.crt -keystore Desktop\mycert.jks -alias changeit //changeit - пароль crt
и затем следовал обычным шагам чтения ssl:
public static SSLSocketFactory acceptMyCertificate(String sslCert) {
final char[] JKS_PASSWORD = "changeit".toCharArray();
final char[] KEY_PASSWORD = "changeit".toCharArray();
System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
try {
final KeyStore keyStore = KeyStore.getInstance("JKS");
String workingDir = System.getProperty("user.dir");
final String path = workingDir+sslCert;
final InputStream is = new FileInputStream(path);
keyStore.load(is, JKS_PASSWORD);
final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, KEY_PASSWORD);
final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
final SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new java.security.SecureRandom());
final SSLSocketFactory socketFactory = sc.getSocketFactory();
return socketFactory;
} catch (GeneralSecurityException exc) {
throw new RuntimeException(exc);
}
catch (IOException exc) {
throw new RuntimeException(exc);
}
}
Теперь я могу отправить на мой mqtt, используя преобразованный файл.jks