- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我们正在研究 Android 的推送通知平台(Google 的 C2DM 的故障转移)我正在使用 Eclipse Paho Java 客户端连接到 mosquitto 代理 (1.0.3)。代理安装在 Ubuntu 12.04(AWS EC2 实例)上我使用非加密的 TCP 连接成功地将客户端连接到服务器。顺便说一句,在调整内核参数后,我能够在一台中型 EC2 机器上为一个代理实例打开 100K 个并发客户端。干得好,蚊子!
现在我正在尝试使用 SSL 建立安全连接。我想使用客户端证书对客户端进行身份验证。我遵循了 mosquito_tls page 中的解释并为服务器和客户端生成 key 和自签名证书。配置服务器以使用 SSL。
对于客户端部分,我查看了 mosquitto_tls_set 的签名并注意到它需要 CA 证书、客户端 key 和证书文件。我认为CA证书用于客户端对服务器进行身份验证,而客户端 key 和证书用于服务器对客户端进行身份验证。我说得对吗?
下面是我在 Java 方面所做的:
当我进行连接时,我从 mosquitto 收到以下错误
OpenSSL Error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
Socket read error on client (null), disconnecting.
编辑:现在我在客户端看到以下异常
javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
完整代码如下
static SSLSocketFactory getSocketFactory (final String caCrtFile, final String crtFile, final String keyFile, final String password) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
X509Certificate caCert = (X509Certificate)reader.readObject();
reader.close();
reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
X509Certificate cert = (X509Certificate)reader.readObject();
reader.close();
reader = new PEMReader(
new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
new PasswordFinder() {
public char[] getPassword() {
return password.toCharArray();
}
}
);
KeyPair key = (KeyPair)reader.readObject();
reader.close();
KeyStore caKs = KeyStore.getInstance("JKS");
caKs.load(null, null);
caKs.setCertificateEntry("ca-certificate", caCert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(caKs);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
ks.setCertificateEntry("certificate", cert);
ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
//ks.setKeyEntry("public-key", key.getPublic(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, password.toCharArray());
SSLContext context = SSLContext.getInstance("SSLv3");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return context.getSocketFactory();
}
mosquito.conf 看起来像这样
# general options
pid_file /home/ubuntu/mosquitto.pid
# persistence
queue_qos0_messages false
persistence false
# logging
log_dest stdout
connection_messages true
log_timestamp false
# default listener
# disable default listener (open only SSL listener)
#port 1883
#max_connections -1
# SSL listener
listener 1883
cafile /home/ubuntu/etc/ca.crt
certfile /home/ubuntu/etc/server.crt
keyfile /home/ubuntu/etc/server.key
require_certificate true
use_identity_as_username true
max_connections -1
最佳答案
好的,在 mosquitto 开发人员(thx,Roger Light)的支持下,我们解决了问题。您在生成证书时提供的详细信息(公司、组织单位、通用名称)在 CA、客户端和服务器证书中必须不同。否则代码可以进行一些小的更改。为了清楚起见,我在这里重新发布了正确的代码和一些注释:
import java.io.*;
import java.nio.file.*;
import java.security.*;
import java.security.cert.*;
import java.security.interfaces.*;
import javax.net.ssl.*;
import org.bouncycastle.jce.provider.*;
import org.bouncycastle.openssl.*;
static SSLSocketFactory getSocketFactory (final String caCrtFile, final String crtFile, final String keyFile, final String password) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
// load CA certificate
PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
X509Certificate caCert = (X509Certificate)reader.readObject();
reader.close();
// load client certificate
reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
X509Certificate cert = (X509Certificate)reader.readObject();
reader.close();
// load client private key
reader = new PEMReader(
new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
new PasswordFinder() {
public char[] getPassword() {
return password.toCharArray();
}
}
);
KeyPair key = (KeyPair)reader.readObject();
reader.close();
// CA certificate is used to authenticate server
KeyStore caKs = KeyStore.getInstance("JKS");
caKs.load(null, null);
caKs.setCertificateEntry("ca-certificate", caCert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(caKs);
// client key and certificates are sent to server so it can authenticate us
KeyStore ks = KeyStore.getInstance("JKS");
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("PKIX");
kmf.init(ks, password.toCharArray());
// finally, create SSL socket factory
SSLContext context = SSLContext.getInstance("TLSv1");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return context.getSocketFactory();
}
关于java - 从 Java 客户端 (Eclipse Paho) 到 mosquitto 代理 : "unknown_ca" 的 SSL 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12997559/
当我使用 paho 和 spring 框架修复应用程序中客户端的一些问题时,我发现了 spring MQTT 集成。我不确定这是否能解决我的问题,我什至不确定这是什么。 有人可以解释一下两者一起使用有
我正在尝试设置一个 mqtt 客户端,但我收到一个 ImportError: 我安装了 paho: pip install paho-mqtt 它说:成功安装 dnspython-1.15.0 pah
我的 raspberrypi 上的以下 python 代码没有连接到我的 mqtt 代理,它只是在打印 Connecting... 后挂起: import paho.mqtt.client as mq
当我通过 MQTTLens 测试发布时,它有效。然而,当我按下按钮时,它确实会触发“on_publish”,但另一端的 on_message 没有收到任何内容;它没有被触发。有两个 Raspberry
我正在使用 Java Paho MQTT 客户端库通过 MQTT 连接到服务器。 库支持使用签名证书进行身份验证和加密的 TLS/SSL。 但是,如果我只是使用用户名和密码进行身份验证(如下所示),而
我的 python paho-mqtt client无法连接到用 java 编写的代理。代理已使用 jks 类型证书启用 SSL 连接。经纪人不在我的管理范围内。 我将 jks 证书转换为 pem 证
如果连接丢失,我的 paho-mqtt 服务无法重新连接到代理。 在连接丢失时,我使用 adb shell 从 Android 客户端 ping 两个代理,并从托管 mosquito 代理的服务器 (
我在笔记本电脑上运行 MQTT Mosquitto 代理。然后我尝试将 2 个 Paho MQTT 客户端连接到它:1)使用 Java Paho 从 Android 手机和 2)使用 Python
有没有一种优雅的方法可以从代理中提取一条消息而不必: 订阅 创建一个 on_message() 接收消息 退订 我问是因为我们使用了一个包含多个字段的 json 消息。当新数据进入时,我只想更新 js
我正在使用适用于 Android 的 Paho MQTT 库,我的应用程序正在交换实时编辑数据。我想在应用程序与代理断开连接时禁用编辑文本,并在重新建立连接时启用它。 第一部分很简单,MqttCall
我正在使用 Eclipse MQTT 库 Paho,但我找不到方法来决定客户端与代理的连接何时建立。 有人知道目前是否有办法做到这一点吗? 我似乎在文档中的 MqttCallback 类中找不到任
我对 paho mqtt 库有一个小问题。我注册了回调函数 MQTTClient_messageArrived 和 MQTTClient_connectionLost。 我在此回调函数中调用 MQTT
我使用 Apache Artemis 作为我的 mqtt 代理。我有一个以主从方式配置的 Artemis 集群。当主服务器发生故障时,备份服务器接管,客户端必须连接到从服务器。主站和从站有不同的IP。
我目前正在开发一个应该在医疗机构中运行的小型“紧急按钮”应用程序。由于该项目的假设之一是独立于 Internet,因此我决定使用在本地 WLAN 中设置服务器的 MQTT。 我已经实现了 Paho A
我正在尝试使用基本的 Eclipse Paho MQTT 客户端版本 1.1.0,用于连接到 CloudAMQP RabbitMQ 实例、订阅主题并接收消息(我从 Web 管理控制台发送的消息)。 如
我已经创建了 mqtt 连接suscribeData(),如下所示,以 24/7 从多个设备接收数据 @RequestMapping("/suscribe") @ResponseBody public
我最近开始使用 paho mqtt for java 和 mqtt,但我坚持使用 mqtt 代理和 paho 客户端本身提供的持久性机制。也许我误解了(可能就是这样)mqtt 上下文中的持久性概念。
我是 MQTT 和树莓派的新手!我正在运行一个客户端脚本,我只是使用另一个脚本发布一条消息。我正在使用自己的 Mosquitto 代理。 客户: import paho.mqtt.client as
我设法在我的 RPi 中的 Paho-MQTT 客户端和我的 VPS 中的 MQTT 代理之间建立了连接。 现在我正在尝试保护 MQTT 连接,并且我已将用户和密码添加到代理。我更改了 mosquit
为了演示 Paho MQTT,我下载了一个 Java 示例。 public class Thermometer { public static final String BROKER_URL
我是一名优秀的程序员,十分优秀!