Search Unity

Bug M2MQTT Argument Exception: unsupported HMAC

Discussion in 'Editor & General Support' started by xofreshxo, Dec 28, 2022.

  1. xofreshxo

    xofreshxo

    Joined:
    Apr 12, 2017
    Posts:
    79
    I am trying to setup an MQTT client in Unity (C#) which would communicate with AWS IoT Core. Here are the steps I've taken:

    1)Generated a .pfx file using the certificate files from AWS:
    openssl pkcs12 -export -in certificate.pem.crt -inkey private.pem.key -out certificate.cert.pfx -certfile AmazonRootCA1.pem


    2)Placed the .pem and .pfx file in the Resources folder of my project. The path for the device certification in the code would be:
    deviceCertPath="Assets/Resources/certificate.cert.pfx"


    3)Added M2Mqtt.net dll to Plugins folder (Downloaded from NuGet)

    4)My code is as follows:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Security.Cryptography.X509Certificates;
    4. using System.Text;
    5. using System.Threading;
    6. using UnityEngine;
    7.  
    8. using uPLibrary.Networking.M2Mqtt;
    9. using uPLibrary.Networking.M2Mqtt.Messages;
    10.  
    11. // Variables
    12.  
    13. private void Start()  
    14. {
    15.     caCert = X509Certificate2.CreateFromCertFile(caCertPath);
    16.     deviceCert = new X509Certificate2(deviceCertPath);
    17.  
    18.     client = new MqttClient(broker, port, true, caCert, deviceCert, MqttSslProtocols.TLSv1_2);
    19.  
    20.     client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
    21.     client.MqttMsgSubscribed += Client_MqttMsgSubscribed;
    22.  
    23.     //Connect
    24.     client.Connect(clientId);
    25.     Debug.Log($"Connected to AWS IoT with client id: {clientId}.");
    26. }
    27.  
    28. // Message Methods
    When I try to run the code I get an error that happens when trying to create the deviceCert:

    Code (CSharp):
    1. ArgumentException: unsupported HMAC
    2. Mono.Security.X509.PKCS12.Decode (System.Byte[] data) (at <b2e147cb24644c1580a142ea3d6c249e>:0)
    3. Mono.Security.X509.PKCS12..ctor (System.Byte[] data, System.String password) (at <b2e147cb24644c1580a142ea3d6c249e>:0)
    4. System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.ImportPkcs12 (System.Byte[] rawData, System.String password) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0)
    5. System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono.ImportPkcs12 (System.Byte[] rawData, Microsoft.Win32.SafeHandles.SafePasswordHandle password) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0)
    6. System.Security.Cryptography.X509Certificates.X509Certificate2ImplMono..ctor (System.Byte[] rawData, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0)
    7. Mono.X509PalImpl.ImportFallback (System.Byte[] data, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0)
    8. Mono.X509PalImplMono.Import (System.Byte[] data, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0)
    9. Mono.SystemCertificateProvider.Import (System.Byte[] data, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags, Mono.CertificateImportFlags importFlags) (at <6d7c4c8dd3624dc596686fb7270ae1e6>:0)
    10. 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)
    11. System.Security.Cryptography.X509Certificates.X509Helper.Import (System.Byte[] rawData, Microsoft.Win32.SafeHandles.SafePasswordHandle password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) (at <6073cf49ed704e958b8a66d540dea948>:0)
    12. System.Security.Cryptography.X509Certificates.X509Certificate..ctor (System.String fileName, System.String password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags) (at <6073cf49ed704e958b8a66d540dea948>:0)
    13. System.Security.Cryptography.X509Certificates.X509Certificate..ctor (System.String fileName) (at <6073cf49ed704e958b8a66d540dea948>:0)
    14. System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromSignedFile (System.String filename) (at <6073cf49ed704e958b8a66d540dea948>:0)
    15. MQTT.Start () (at Assets/Circulate/Scripts/Networking/MQTT/MQTT.cs:32)
    The current .pfx file does not have a password, although I've attempted to use one with a password and got the same error. When I check the details of the certificates, both have a signature hash algorithm of sha256. I'm not sure why I am receiving this error and I haven't been able to find much information regarding unsupported HMAC. I've been able to run the same code in a .Net Framework console application. I suspect it may have to do with the Mono version in Unity (I've tried 2021.3 and 2022.2), but it's just a hunch. Any help is appreciated, thank you!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    Unity generally is a little behind current .Net stuff because anything they add to their platform must be supported on all targets, ranging from the AOT targets to WebGL, which is also pseudo-AOT now, not to mention all the limited game console targets like Nintendo.

    One possible option is to find an older version of this DLL that works with Unity... there might even be a full solution on github.
     
  3. xofreshxo

    xofreshxo

    Joined:
    Apr 12, 2017
    Posts:
    79
    So looking into this further, I don't think it's an issue with the M2MQTT DLL, as the issue occurs during the X509Certificate creation. I think it has to do with System.Security.Cryptography.X509Certificates calling an older version of Mono.Security.X509.PKCS12.Decode which may not have the supported HMAC.
     
    SajadA likes this.
  4. Reahreic

    Reahreic

    Joined:
    Mar 23, 2011
    Posts:
    254
    Were you ever able to resolve this? I've been trying to get Unity to accept an X509CErtificate that's passed in as a byte[] but am unable to get past the X509Certificate2ImplMono constructor.
     
  5. codecustard

    codecustard

    Joined:
    Jun 5, 2018
    Posts:
    2
    Try add
    Code (CSharp):
    1. -macalg SHA1 -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES
    when converting.

    That is what I did.
     
    daniel414, Mogul-CT3 and togawa83 like this.