线程“main”中的异常java.io.IOException:sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:658)中的密钥库格式无效

时间:2017-09-23 13:19:59

标签: java ssl-certificate keystore hivemq

我有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文件,我可以使用mqtt-spy登录到我的hivemq服务器。 用户名:abcd 密码:WXYZ 安全选项卡-TLS   模式:CA证书   协议:TLSv1 CA证书文件:mycert.zip 我正在浏览不同的网站但现在得到答案。

1 个答案:

答案 0 :(得分:0)

通过使用以下命令将.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);
    }
}

现在我可以使用转换后的.jks文件发送到我的mqtt