【问题标题】:ios xcode9.0 swift4.0 MQTT - How to use certificate to connect to MQTT server?ios xcode9.0 swift4.0 MQTT - 如何使用证书连接MQTT服务器?
【发布时间】:2018-07-04 14:51:40
【问题描述】:

这是我想在 iphone 应用中完成的任务:

  1. 从 test.mosquitto.org 下载并安装证书“mosquitto.org.crt”

  2. 在8883端口连接mqtt服务器“test.mosquitto.org”

  3. 预计会在调试消息中看到“连接成功”
  4. 退出应用,删除iphone中的证书
  5. 返回应用程序并重新尝试连接到 8883 端口的 mqtt 服务器
  6. 预计会看到:连接失败

我试过 CocoaMQTT: https://github.com/emqtt/CocoaMQTT 但是即使证书已经被删除,CocoaMQTT 仍然可以成功连接到服务器。

这是我从 cocoaMQTT 示例中修改的代码:

import UIKit
import CocoaMQTT

class ViewController: UIViewController {
    var mqtt: CocoaMQTT?

    override func viewDidLoad() {
        super.viewDidLoad()

        mqttSetting()
    }



    func mqttSetting() {
        let clientID: String = "testID123456789"
        let mqttServer: String = "test.mosquitto.org"
        let mqttPort: UInt16 = 8883
        let useSSL: Bool = true

        mqtt = CocoaMQTT(clientID: clientID, host: mqttServer, port: mqttPort)
        mqtt!.username = nil
        mqtt!.password = nil
        mqtt!.keepAlive = 60
        mqtt!.delegate = self

        if useSSL == true{
            mqtt!.enableSSL = true
            mqtt!.allowUntrustCACertificate = true
        }

        mqtt!.connect()
    }

}

extension ViewController: CocoaMQTTDelegate {
    // Optional ssl CocoaMQTTDelegate
    func mqtt(_ mqtt: CocoaMQTT, didReceive trust: SecTrust, completionHandler: @escaping (Bool) -> Void) {
        TRACE("trust: \(trust)")
        /// Validate the server certificate
        ///
        /// Some custom validation...
        ///
        /// if validatePassed {
        ///     completionHandler(true)
        /// } else {
        ///     completionHandler(false)
        /// }
        completionHandler(true)
    }

    func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
        TRACE("ack: \(ack)")

        if ack == .accept {
            mqtt.subscribe("chat/room/animals/client/+", qos: CocoaMQTTQOS.qos1)


        }
    }

    func mqtt(_ mqtt: CocoaMQTT, didStateChangeTo state: CocoaMQTTConnState) {
        TRACE("new state: \(state)")
    }

    func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {
        TRACE("message: \(String(describing: message.string?.description)), id: \(id)")
    }

    func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {
        TRACE("id: \(id)")
    }

    func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16 ) {
        TRACE("message: \(String(describing: message.string?.description)), id: \(id)")

    }

    func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopic topic: String) {
        TRACE("topic: \(topic)")
    }

    func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopic topic: String) {
        TRACE("topic: \(topic)")
    }

    func mqttDidPing(_ mqtt: CocoaMQTT) {
        TRACE()
    }

    func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
        TRACE()
    }

    func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {
        TRACE("\(err.debugDescription)")
    }
}

extension ViewController {
    func TRACE(_ message: String = "", fun: String = #function) {
        let names = fun.components(separatedBy: ":")
        var prettyName: String
        if names.count == 1 {
            prettyName = names[0]
        } else {
            prettyName = names[1]
        }

        if fun == "mqttDidDisconnect(_:withError:)" {
            prettyName = "didDisconect"
        }

        print("[TRACE] [\(prettyName)]: \(message)")
    }
}

上面的代码在调试窗口中给出了以下结果(我已经在我的 iPhone 中删除了 test.mosquitto.org 的证书):

[TRACE] [didStateChangeTo]: new state: connecting
[TRACE] [didReceive]: trust: <SecTrustRef: 0x170129420>
[TRACE] [didStateChangeTo]: new state: connected
[TRACE] [didConnectAck]: ack: accept
[TRACE] [didSubscribeTopic]: topic: chat/room/animals/client/+
[TRACE] [mqttDidPing]: 
[TRACE] [mqttDidReceivePong]: 
[TRACE] [mqttDidPing]: 
[TRACE] [mqttDidReceivePong]: 

我预计到 mqtt 服务器的连接不应该成功,因为我已经删除了 iPhone 中的证书。但是,连接仍然成功,这不是我的预期结果。知道该怎么做吗?

【问题讨论】:

  • 这太宽泛了,选择您提到的库之一并编辑问题以包含您尝试过的代码和您遇到的错误,然后有人会帮助您修复它。
  • 嗨,哈迪尔布!感谢您的回复。我已经编辑了这个问题并专注于使用 CocoaMQTT。你有什么解决办法吗?

标签: ios swift xcode certificate mqtt


【解决方案1】:

您的服务器可能使用单向认证。

您可以使用单向认证:

mqtt!.enableSSL = true

本地不需要证书。

如果你想信任所有不信任的 CA 证书,你可以这样做:

mqtt.allowUntrustCACert = true

(p12是2路认证)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 1970-01-01
    相关资源
    最近更新 更多