如何在iOS和Android上为IoT Edge SDK连接关联证书
连接IoT Edge设备的移动端证书处理方案
Android 端实现
方式1:编程将证书添加到系统存储
- 先把PEM格式证书转为
X509Certificate对象:CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream certInputStream = new ByteArrayInputStream(certPem.getBytes()); X509Certificate cert = (X509Certificate) cf.generateCertificate(certInputStream); - 通过
KeyChain类触发系统弹窗,引导用户确认导入证书到系统信任存储:
注意:此操作必须经过用户手动授权,Android系统不允许静默导入证书到系统存储。Intent intent = KeyChain.createInstallIntent(); intent.putExtra(KeyChain.EXTRA_CERTIFICATE, cert.getEncoded()); intent.putExtra(KeyChain.EXTRA_NAME, "IoT Edge CA Cert"); startActivityForResult(intent, INSTALL_CERT_REQUEST_CODE);
方式2:绕开系统存储,直接在SDK中指定证书
如果不想依赖系统存储,可直接在MQTT客户端初始化时加载证书:
- 构建自定义
SSLSocketFactory,加载CA证书:SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); keyStore.setCertificateEntry("iot-edge-ca", cert); tmf.init(keyStore); sslContext.init(null, tmf.getTrustManagers(), new SecureRandom()); - 将自定义
SSLSocketFactory传入MQTT客户端配置(以Eclipse Paho SDK为例):MqttConnectOptions options = new MqttConnectOptions(); options.setSocketFactory(sslContext.getSocketFactory());
iOS 端实现
方式1:编程将证书添加到钥匙串
- 把PEM证书转为DER格式(或直接使用DER证书文件),通过
Security框架导入APP专属钥匙串容器:
注意:APP只能将证书导入自身的钥匙串容器,若要让系统全局信任该证书,需引导用户前往「设置」→「通用」→「关于本机」→「证书信任设置」手动启用。func installCertificate(certData: Data) { let addQuery: [CFString: Any] = [ kSecClass: kSecClassCertificate, kSecAttrLabel: "IoT Edge CA Cert" as CFString, kSecValueData: certData, kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly ] let status = SecItemAdd(addQuery as CFDictionary, nil) switch status { case errSecSuccess: print("证书导入成功") case errSecDuplicateItem: print("证书已存在") default: print("导入失败,错误码:\(status)") } }
方式2:绕开钥匙串,直接在MQTT客户端加载证书
无需导入钥匙串,直接在MQTT客户端配置中指定本地证书文件:
- 读取APP Bundle中的证书文件:
guard let certPath = Bundle.main.path(forResource: "iot-edge-ca", ofType: "pem"), let certData = try? Data(contentsOf: URL(fileURLWithPath: certPath)) else { print("无法读取证书文件") return } - 构建证书对象并传入MQTT客户端(以MQTTNIO为例):
let certificate = SecCertificateCreateWithData(nil, certData as CFData)! let trustPolicy = MQTTSecurityPolicy(pinnedCertificates: [certificate]) trustPolicy.validatesDomainName = true let client = MQTTClient( host: "your-iot-edge-host", port: 8883, securityPolicy: trustPolicy )
内容的提问来源于stack exchange,提问作者Philip Coupar
相关产品推荐
相关产品推荐

