我正在尝试使用Smack 4.0.5 Api连接到Vines XMPP,作为以测试为导向的成长面向对象软件的一部分。我很难找到任何描述如何使用TLS连接的文档。几个线程已经提供了如下所示的示例,但由于以下原因(因为我认为不安全)选项失败,因此:
ConnectionConfiguration connectionConfig = new ConnectionConfiguration(XMPP_HOSTNAME, 5222);
connectionConfig.setDebuggerEnabled(true);
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
sslContext.init(null, new TrustManager[] {tm}, null);
connectionConfig.setCustomSSLContext(sslContext);
this.connection = new XMPPTCPConnection(connectionConfig);
this.connection.connect();
this.connection.login(format(ITEM_ID_AS_LOGIN, itemId), AUCTION_PASSWORD, AUCTION_RESOURCE);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("connecting failed", e);
}
带
org.jivesoftware.smack.sasl.SASLErrorException: SASLError using PLAIN: not-authorized
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:348)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.login(XMPPTCPConnection.java:244)
at uk.me.paulswilliams.auction.fakes.FakeAuctionServer.<init>(FakeAuctionServer.java:60)
at uk.me.paulswilliams.auction.AuctionSniperEndToEndTest.<init>(AuctionSniperEndToEndTest.java:10)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:195)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:244)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:241)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Vines提供了一个自签名证书,我试图通过将公共证书复制到客户端,使用OS X上的Java控制面板注册它来实现'安全'方式,并使用以下代码: / p>
try {
ConnectionConfiguration connectionConfig = new ConnectionConfiguration(XMPP_HOSTNAME, 5222);
connectionConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
this.connection = new XMPPTCPConnection(connectionConfig);
this.connection.connect();
this.connection.login(format(ITEM_ID_AS_LOGIN, itemId), AUCTION_PASSWORD, AUCTION_RESOURCE);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("connection failed");
}
然而,在这种情况下,我继续收到:
Nov 13, 2014 8:49:11 PM org.jivesoftware.smack.XMPPConnection callConnectionClosedOnErrorListener
WARNING: Connection closed with error
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
我怀疑两者都接近工作,并且由于这项工作的性质,安全性确实不是一个考虑因素。
编辑:
我现在尝试使用以下方法将Vines证书导入我的JVM keystone:
sudo /Library/Java/Home/bin/keytool --import --alias "localhost" -file localhost.crt -keystore /Library/Java/Home/lib/security/cacerts
我已经指定了别名来匹配服务器名称'localhost',虽然服务器也称为'rails-dev-box',但我没有在java客户端中使用该名称。我是否还需要导入ca-bundle.crt CA? Java是否应该根据服务器名称获取此证书,或者我是否需要明确指示Java这样做?
答案 0 :(得分:2)
在Flow的帮助下,我已经找到了这个有效的解决方案:
ConnectionConfiguration connectionConfig = new ConnectionConfiguration(XMPP_HOSTNAME, 5222);
connectionConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
System.setProperty("javax.net.ssl.trustStore", "akeystore.jks");
this.connection = new XMPPTCPConnection(connectionConfig);
this.connection.connect();
this.connection.login(format(ITEM_ID_AS_LOGIN, itemId), AUCTION_PASSWORD, AUCTION_RESOURCE);
我用:
创建了密钥库keytool -import -alias localhost -file ~/src/auctionsniperjava/localhost.crt -keystore akeystore.jks