Unity中M2MQTT连接AWS IoT Core遇unsupported HMAC异常求助
Unity AWS IoT Core MQTT客户端证书加载错误(unsupported HMAC)解决
操作流程
- 使用OpenSSL将AWS提供的证书转换为PFX格式:
openssl pkcs12 -export -in certificate.pem.crt -inkey private.pem.key -out certificate.cert.pfx -certfile AmazonRootCA1.pem
- 将
.pem和.pfx文件放入项目Resources文件夹,代码中设备证书路径设置为:deviceCertPath="Assets/Resources/certificate.cert.pfx" - 导入NuGet下载的
M2Mqtt.netDLL到项目Plugins文件夹 - 核心实现代码:
using System.Collections; using System.Collections.Generic; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; using UnityEngine; using uPLibrary.Networking.M2Mqtt; using uPLibrary.Networking.M2Mqtt.Messages; // 变量定义 private void Start() { caCert = X509Certificate2.CreateFromCertFile(caCertPath); deviceCert = new X509Certificate2(deviceCertPath); client = new MqttClient(broker, port, true, caCert, deviceCert, MqttSslProtocols.TLSv1_2); client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived; client.MqttMsgSubscribed += Client_MqttMsgSubscribed; // 连接AWS IoT Core client.Connect(clientId); Debug.Log($"Connected to AWS IoT with client id: {clientId}."); } // 消息处理方法
错误详情
创建deviceCert对象时触发如下错误:
ArgumentException: unsupported HMAC Mono.Security.X509.PKCS12.Decode (System.Byte[] data) (at <b2e147cb24644c1580a142ea3d6c249e>:0) Mono.Security.X509.PKCS12..ctor (System.Byte[] data, System.String password) (at <b2e147cb24644c1580a142ea3d6c249e>:0) System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.ImportPkcs12 (System.Byte[] rawData, System.String password) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0) System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.ImportPkcs12 (System.Byte[] rawData, Microsoft.Win32.SafeHandles.SafePasswordHandle password) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0) System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono..ctor (System.Byte[] rawData, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0) Mono.X509PalImpl.ImportFallback (System.Byte[] data, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0) Mono.X509PalImplMono.Import (System.Byte[] data, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0) Mono.SystemCertificateProvider.Import (System.Byte[] data, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, Mono.CertificateImportFlags importFlags) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0) Mono.SystemCertificateProvider.Mono.ISystemCertificateProvider.Import (System.Byte[] data, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, Mono.CertificateImportFlags importFlags) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0) System.Security.Cryptography.X509Certificates.X509Helper.Import (System.Byte[] rawData, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) (at <6073cf49ed704e958b8a66d540dea948>:0) System.Security.Cryptography.X509Certificates.X509Certificate..ctor (System.String fileName, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) (at <6073cf49ed704e958b8a66d540dea948>:0) System.Security.Cryptography.X509Certificates.X509Certificate..ctor (System.String fileName) (at <6073cf49ed704e958b8a66d540dea948>:0) System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromSignedFile (System.String filename) (at <6073cf49ed704e958b8a66d540dea948>:0) MQTT.Start () (at Assets/Circulate/Scripts/Networking/MQTT/MQTT.cs:32)
注:已尝试为PFX设置密码,错误依旧;证书签名哈希算法均为SHA256
解决方案
1. 重新生成兼容的PFX文件
Mono运行时对PKCS12格式的HMAC算法支持有限,生成PFX时显式指定SHA256作为MAC算法:
# 无密码生成 openssl pkcs12 -export -in certificate.pem.crt -inkey private.pem.key -out certificate.cert.pfx -certfile AmazonRootCA1.pem -macalg SHA256 # 带密码生成(替换为自定义密码) openssl pkcs12 -export -in certificate.pem.crt -inkey private.pem.key -out certificate.cert.pfx -certfile AmazonRootCA1.pem -macalg SHA256 -passout pass:YourCustomPassword
2. 调整代码中证书加载逻辑
Unity中加载PFX时,指定X509KeyStorageFlags参数,规避Mono的存储权限问题:
// 无密码加载 deviceCert = new X509Certificate2(deviceCertPath, "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); // 带密码加载(替换为你的密码) deviceCert = new X509Certificate2(deviceCertPath, "YourCustomPassword", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
3. 替换为更兼容的MQTT库(备选)
M2Mqtt库版本较旧,对Unity和Mono的兼容性有限,可替换为现代MQTT库:
- 导入MQTTnet的Unity兼容版本到
Plugins文件夹 - 使用MQTTnet的API加载证书并建立与AWS IoT Core的连接,该库对PKCS12格式支持更完善
内容的提问来源于stack exchange,提问作者Adam Ryason
相关产品推荐
相关产品推荐

