如何在EclipsePAHOJavaMQTT客户机和Mosquitto代理之间创建PSK连接?

如何在EclipsePAHOJavaMQTT客户机和Mosquitto代理之间创建PSK连接?,java,ssl,mqtt,mosquitto,Java,Ssl,Mqtt,Mosquitto,我试图在Mosquito mqtt代理和使用EclipsePAHO客户端库的Java编写的应用程序之间配置预共享密钥加密连接 我已经成功地使用未加密和SSL在两者之间建立了连接,其中服务器证书经过身份验证,但没有客户端证书 我希望通过使用预共享密钥对连接进行加密(身份验证不重要),mosquitto代理肯定支持预共享密钥,但我不确定EclipsePAHO库是否支持它 该库为您提供了两种配置安全连接的不同方法。要么通过 setSSLProperties(java.util.Properties p

我试图在Mosquito mqtt代理和使用EclipsePAHO客户端库的Java编写的应用程序之间配置预共享密钥加密连接

我已经成功地使用未加密和SSL在两者之间建立了连接,其中服务器证书经过身份验证,但没有客户端证书

我希望通过使用预共享密钥对连接进行加密(身份验证不重要),mosquitto代理肯定支持预共享密钥,但我不确定EclipsePAHO库是否支持它

该库为您提供了两种配置安全连接的不同方法。要么通过

setSSLProperties(java.util.Properties props)
方法-利用以下属性:

com.ibm.ssl.protocol
com.ibm.ssl.contextProvider
com.ibm.ssl.keyStore
com.ibm.ssl.keyStorePassword
com.ibm.micro.security.Password.obfuscate(char[] password). 
com.ibm.ssl.keyStoreType
com.ibm.ssl.keyStoreProvider
com.ibm.ssl.trustStore
com.ibm.ssl.trustStorePassword
com.ibm.micro.security.Password.obfuscate(char[] password).
com.ibm.ssl.trustStoreType
com.ibm.ssl.trustStoreProvider
com.ibm.ssl.enabledCipherSuites
com.ibm.ssl.keyManager
com.ibm.ssl.trustManager
或者通过

setSocketFactory(javax.net.SocketFactory socketFactory)
方法

有人对我使用的工具和库有经验吗?有人能为我提供一些建议吗

是否可以创建一个ssl套接字工厂,该工厂能够返回一个套接字,该套接字可以处理我需要的PSK实现


感谢您的帮助:-)

我敢打赌,泛美卫生组织的客户不支持现成的TLS PSK。例如,TLS-PSK支持在openssl中只是相对较新的,所以它没有得到广泛支持也就不足为奇了。例如,Python不支持它

我所知道的唯一支持TLS-PSK的MQTT客户机是那些基于mosquitto C/C++库的客户机,如mosquitto_pub/mosquitto_sub


您最好将问题指向Paho邮件列表。

Paho客户端依赖于JVM运行时中提供的任何安全密码等;泛美卫生组织本身不提供任何援助

据我所知,主流JVM提供商都不支持TLS-PSK。可以添加来自第三方的支持,例如

您可能还需要检查关于此主题的以下(目前尚未回答)问题:


是的,可以向paho mqtt客户端传递使用bouncy castle进行TLS-PSK的SocketFactory。不过,它并不那么漂亮(也许有人有更好的解决方案?)

我的答案基于以下示例: 从这里可以得到内部类Z_PSKIdentity和MyPSKTlsClient

那么你需要一个这样的SocketFactory:

class PskSocketFactory extends SSLSocketFactory {

    public Socket createSocket() {
        SSLSocket mySocket = new SSLSocket() {
            TlsClientProtocol protocol = null;

            @Override
            public void startHandshake() throws IOException {
                try {
                    protocol = new TlsClientProtocol(super.getInputStream(), super.getOutputStream(), new SecureRandom());
                } catch (Exception e) {
                    e.printStackTrace();
                }

                Z_PSKIdentity pskIdentity = new Z_PSKIdentity();
                MyPSKTlsClient client = new MyPSKTlsClient(pskIdentity);
                protocol.connect(client);
            }

            @Override
            public InputStream getInputStream() throws IOException {
                return protocol.getInputStream();
            }

            @Override
            public OutputStream getOutputStream() throws IOException {
                return protocol.getOutputStream();
            }

            return mySocket;
        }
    }

}
public int[] getCipherSuites() {
    return new int[] { CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA };
}
SSLSocketFactory和SSLSocket中都有很多抽象方法。您需要实现它们,但据我所知,它们没有被使用,所以您可以让IDE使用无意义的实体生成它们。为了便于阅读,我把它们从代码中删掉了

我不知道mosquitto的情况,但这种方法对我来说是有效的,stunnel后面有一个明文HiveMQ作为TLS代理

如果需要更改/选择密码,只需在MyPSKTlsClient中重写GetCipherSuite,如下所示:

class PskSocketFactory extends SSLSocketFactory {

    public Socket createSocket() {
        SSLSocket mySocket = new SSLSocket() {
            TlsClientProtocol protocol = null;

            @Override
            public void startHandshake() throws IOException {
                try {
                    protocol = new TlsClientProtocol(super.getInputStream(), super.getOutputStream(), new SecureRandom());
                } catch (Exception e) {
                    e.printStackTrace();
                }

                Z_PSKIdentity pskIdentity = new Z_PSKIdentity();
                MyPSKTlsClient client = new MyPSKTlsClient(pskIdentity);
                protocol.connect(client);
            }

            @Override
            public InputStream getInputStream() throws IOException {
                return protocol.getInputStream();
            }

            @Override
            public OutputStream getOutputStream() throws IOException {
                return protocol.getOutputStream();
            }

            return mySocket;
        }
    }

}
public int[] getCipherSuites() {
    return new int[] { CipherSuite.TLS_PSK_WITH_AES_256_CBC_SHA };
}

感谢您提供的信息-我不知道TLS-PSK最近才被引入openssl,所以这是有意义的。也谢谢你的建议-我尝试通过邮件列表联系,但在尝试发送查询或加入请求几个小时后,我收到了很多“传递失败”的通知。。。但我会坚持下去:)