我正在尝试与mqtt mosquitto经纪人建立联系。 我生成以下密钥和证书:https://mosquitto.org/man/mosquitto-tls-7.html
然后这是我的代码:
public class App {
public static void main(String[] args) {
String serverUrl = "ssl://129.6.60.24:8883";
String caFilePath = "./src/main/resources/ca.crt";
String clientCrtFilePath = "./src/main/resources/brokerCertificate.crt";
String clientKeyFilePath = "./src/main/resources/ca.key";
String mqttUserName = "cpcc";
String mqttPassword = "1qaz!QAZ1qaz";
MqttClient client;
try {
client = new MqttClient(serverUrl, "TestBedBroker");
client.setCallback(new SimpleMqttCallBack());
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(mqttUserName);
options.setPassword(mqttPassword.toCharArray());
SSLSocketFactory socketFactory = SslUtil.getSocketFactory(caFilePath, clientCrtFilePath, clientKeyFilePath, "1qaz!QAZ1qaz");
options.setSocketFactory(socketFactory);
System.out.println("starting connect the server...");
client.connect(options);
System.out.println("connected!");
Thread.sleep(1000);
client.disconnect();
System.out.println("disconnected!");
}
catch (MqttException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
public class SslUtil {
public static SSLSocketFactory getSocketFactory(final String caCrtFile, final String crtFile, final String keyFile, final String password) throws Exception {
Security.addProvider(new BouncyCastleProvider());
// load CA certificate
X509Certificate caCert = null;
FileInputStream fis = new FileInputStream(caCrtFile);
BufferedInputStream bis = new BufferedInputStream(fis);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
while (bis.available() > 0) {
caCert = (X509Certificate) cf.generateCertificate(bis);
// System.out.println(caCert.toString());
}
// load client certificate
bis = new BufferedInputStream(new FileInputStream(crtFile));
X509Certificate cert = null;
while (bis.available() > 0) {
cert = (X509Certificate) cf.generateCertificate(bis);
// System.out.println(caCert.toString());
}
// load client private key
PEMParser pemParser = new PEMParser(new FileReader(keyFile));
Object object = pemParser.readObject();
PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
KeyPair key;
if (object instanceof PEMEncryptedKeyPair) {
System.out.println("Encrypted key - we will use provided password");
key = converter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(decProv));
} else {
System.out.println("Unencrypted key - no password needed");
key = converter.getKeyPair((PEMKeyPair) object);
}
pemParser.close();
// CA certificate is used to authenticate server
KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
caKs.load(null, null);
caKs.setCertificateEntry("ca-certificate", caCert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(caKs);
// client key and certificates are sent to server so it can authenticate
// us
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
ks.setCertificateEntry("certificate", cert);
ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[] { cert });
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, password.toCharArray());
// finally, create SSL socket factory
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return context.getSocketFactory();
}
}
但是当我运行我的程序时,我有:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
所以我尝试按照许多帖子的建议将我的证书添加到Java信任存储区但是我得到了同样的错误,我完全不知道我错过了什么。