【问题标题】:TLS (v1.2) client certificate only sometimes required. Why?仅有时需要 TLS (v1.2) 客户端证书。为什么?
【发布时间】:2020-10-07 12:16:30
【问题描述】:

我已经设置了一个 mosquitto MQTT 服务器并创建了所有内容来加密通信。证书是使用此脚本here 创建的。一切正常。证书以 openssl verify -CAfile ca.crt cool-server.crt 签出为“ok”。

但我不明白为什么在不同的客户端上会有不同。

代理在 Ubuntu 18 服务器上运行。在这里配置:

root@cool-server:~# cat /etc/mosquitto/conf.d/default.conf 
allow_anonymous false
password_file /etc/mosquitto/passwd

listener 1883 localhost

listener 8883

cafile /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/cool-server.crt
keyfile /etc/mosquitto/certs/cool-server.key

require_certificate true
#require_certificate false # tried this too

tls_version tlsv1.2

root@cool-server:~# cat /etc/mosquitto/mosquitto.conf 
# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example

pid_file /var/run/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

log_type all
log_dest file /var/log/mosquitto/mosquitto.log

include_dir /etc/mosquitto/conf.d

我可以通过它连接到它

  • mosquitto_sub / _pub(需要 ca.cert 文件)
  • 带有 AsyncMqttCliet 的基于 Arduino 的 ESP8266(需要从证书中使用 openssl 派生的指纹)
  • 自定义 Android 应用程序(什么都不需要???) (以下所有代码)。

问题是:

1.为什么有些客户需要指纹证书而有些则不需要?

据我所知,TLS/SSL 可以只在服务器端使用证书来保护连接,但我不确定。 Android 应用程序无需任何证书或指纹即可连接到我的代理,而 mosquitto_pub 仅适用于 cacert。即使我使用require_certificate false 配置代理,客户端仍然需要指定cacert。 --insecure 不能解决这个问题。另一方面,我的 ESP8266 只需要一个短指纹。

2。我的所有连接(尤其是 Android 连接)都是安全/加密的吗?

ESP8266 / Arduino

const uint8_t mqttCertFingerprint[] = {0xA6, 0x4D, 0x9F, 0x43B, 0x80, 0xB7, 0xB2, 0x9A, 0x9D, 0xCB, 0xC9, 0xF7, 0xAA, 0xCC, 0x30, 0xEF, 0xF4, 0xFC, 0xD3, 0x31};
mqttClient_.setSecure(true);
mqttClient_.addServerFingerprint(mqttCertFingerprint);

重击

mosquitto_pub -h cool-server.com -p 8883 -u user -P Password -t "topic/name" -m "hello" --cafile path/to/ca.crt

安卓

       if (serverUri.contains("ssl")) {
        class TrustEveryoneManager implements X509TrustManager {
            public void checkClientTrusted(X509Certificate[] arg0, String arg1){}
            public void checkServerTrusted(X509Certificate[] arg0, String arg1){}
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        }

        SSLContext sslContext = SSLContext.getInstance("tls");
        sslContext.init(null, new TrustManager[]{new TrustEveryoneManager()}, new SecureRandom());

        mqttConnectOptions.setSocketFactory(sslContext.getSocketFactory());
    }

【问题讨论】:

标签: ssl ssl-certificate mqtt tls1.2 mosquitto


【解决方案1】:

假设您没有使用自签名证书。

mosquitto_pub/sub 和 PubSubClient 库都需要 CA 证书,因为它们没有包含来自证书颁发机构的受信任证书列表的内置信任存储。

在 Android 上,有一个烘焙的 Trust Store。

在 Linux 上,您通常可以将 mosquitto 工具指向 /etc/ssl/certs/,以使用操作系统随附的 Trust Store CA 证书。

更新:

  1. 只要代理在客户端连接时提供完整的证书链,证书指纹就足以验证代理证书。客户端可以检查代理证书是否由 CA 证书签名,并且 CA 证书指纹与提供的指纹匹配。

  2. 不,您的 Android 客户端不安全。您已明确告诉 Android 信任代理提供的任何证书,这意味着任何人都可以在中间人攻击您的 Android 应用程序,而您永远无法分辨。

【讨论】:

  • 感谢您的回答。但是 esp8266 应用程序“仅”使用指纹是否安全?如果它是安全的,为什么 mosquitto 客户端只使用证书安全,而 esp8266 只需要指纹?
  • 是的,esp8266 应用程序是安全的,但它需要一系列额外的步骤来生成指纹,这会丢失很多有用的信息并明确地将您限制为单个证书提供者。至于为什么 mosquitto 想要 CA 证书(或 CA 证书的集合),是因为开发人员选择使用易于获得的公共 CA 证书列表。
猜你喜欢
  • 2020-08-16
  • 1970-01-01
  • 2021-07-01
  • 2019-10-25
  • 1970-01-01
  • 1970-01-01
  • 2018-11-28
  • 2018-08-11
  • 2017-04-08
相关资源
最近更新 更多