You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中M2MQTT连接AWS IoT Core遇unsupported HMAC异常求助

Unity AWS IoT Core MQTT客户端证书加载错误(unsupported HMAC)解决

操作流程

  1. 使用OpenSSL将AWS提供的证书转换为PFX格式:
openssl pkcs12 -export -in certificate.pem.crt -inkey private.pem.key -out certificate.cert.pfx -certfile AmazonRootCA1.pem
  1. 将.pem和.pfx文件放入项目Resources文件夹,代码中设备证书路径设置为:deviceCertPath="Assets/Resources/certificate.cert.pfx"
  2. 导入NuGet下载的M2Mqtt.net DLL到项目Plugins文件夹
  3. 核心实现代码:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 00:35:30