Security Best Practices
The HiveMQ MQTT client for .NET is designed with security in mind, providing multiple layers of protection for your MQTT communications. This guide covers security best practices and the security features available in the client.
Always enable TLS encryption and use proper authentication in production environments. Never deploy with AllowInvalidBrokerCertificates enabled.
Overview
| Security Feature | Purpose | Documentation |
|---|---|---|
| TLS/SSL Encryption | Encrypts all traffic between client and broker | Connection Options |
| SecureString Passwords | Prevents password exposure in memory | This page |
| X.509 Client Certificates | Strong certificate-based authentication | Client Certificates |
| Username/Password Auth | Basic authentication with secure handling | Connect with Auth |
TLS/SSL Encryption
Always use TLS encryption when connecting to MQTT brokers, especially over the internet. TLS protects your data from eavesdropping and man-in-the-middle attacks.
Enable TLS
var options = new HiveMQClientOptionsBuilder()
.WithBroker("your-broker.hivemq.cloud")
.WithPort(8883) // Standard TLS port
.WithUseTls(true)
.Build();
var client = new HiveMQClient(options);
await client.ConnectAsync().ConfigureAwait(false);
WebSocket with TLS
For WebSocket connections, use the wss:// protocol:
var options = new HiveMQClientOptionsBuilder()
.WithWebSocketServer("wss://your-broker.hivemq.cloud:8884/mqtt")
.Build();
Certificate Validation
The AllowInvalidBrokerCertificates option should only be used in development environments. Disabling certificate validation exposes your application to man-in-the-middle attacks.
// DEVELOPMENT ONLY - Never use in production!
var options = new HiveMQClientOptionsBuilder()
.WithBroker("dev-broker.localhost")
.WithPort(8883)
.WithUseTls(true)
.WithAllowInvalidBrokerCertificates(true) // ⚠️ Dev only!
.Build();
SecureString for Credentials
Starting with v0.32.0, the HiveMQ client supports SecureString for handling sensitive credentials. SecureString provides enhanced security by:
- Preventing memory exposure: The password is encrypted in memory
- Reducing attack surface: Plain text passwords don't linger in the managed heap
- Supporting secure disposal: Memory can be explicitly cleared when no longer needed
Using SecureString for Passwords
using System.Security;
using HiveMQtt.Client;
// Create a SecureString for the password
var securePassword = new SecureString();
foreach (char c in GetPasswordFromSecureSource())
{
securePassword.AppendChar(c);
}
securePassword.MakeReadOnly();
var options = new HiveMQClientOptionsBuilder()
.WithBroker("your-broker.hivemq.cloud")
.WithPort(8883)
.WithUseTls(true)
.WithUserName("your-username")
.WithPassword(securePassword) // SecureString overload
.Build();
var client = new HiveMQClient(options);
await client.ConnectAsync().ConfigureAwait(false);
Using SecureString with Client Certificates
Password-protected certificates also support SecureString:
using System.Security;
using HiveMQtt.Client;
// Create SecureString for certificate password
var certPassword = new SecureString();
foreach (char c in GetCertPasswordFromSecureSource())
{
certPassword.AppendChar(c);
}
certPassword.MakeReadOnly();
var options = new HiveMQClientOptionsBuilder()
.WithBroker("your-broker.hivemq.cloud")
.WithPort(8883)
.WithUseTls(true)
.WithClientCertificate("path/to/client-cert.pfx", certPassword)
.Build();
Reading Passwords Securely
Here are patterns for reading passwords without exposing them as plain strings:
From Console Input
static SecureString ReadPasswordFromConsole()
{
var password = new SecureString();
ConsoleKeyInfo key;
Console.Write("Enter password: ");
while ((key = Console.ReadKey(true)).Key != ConsoleKey.Enter)
{
if (key.Key == ConsoleKey.Backspace && password.Length > 0)
{
password.RemoveAt(password.Length - 1);
Console.Write("\b \b");
}
else if (key.Key != ConsoleKey.Backspace)
{
password.AppendChar(key.KeyChar);
Console.Write("*");
}
}
Console.WriteLine();
password.MakeReadOnly();
return password;
}
From Environment Variables (with immediate clearing)
static SecureString GetPasswordFromEnvironment(string variableName)
{
var plainPassword = Environment.GetEnvironmentVariable(variableName);
if (string.IsNullOrEmpty(plainPassword))
{
throw new InvalidOperationException($"Environment variable {variableName} not set");
}
var securePassword = new SecureString();
foreach (char c in plainPassword)
{
securePassword.AppendChar(c);
}
securePassword.MakeReadOnly();
// Clear the environment variable from the current process
Environment.SetEnvironmentVariable(variableName, null);
return securePassword;
}
Deprecation of Plain String Methods
The plain string overloads for password methods are marked as obsolete and will generate compiler warnings:
// ⚠ ️ This generates a compiler warning
var options = new HiveMQClientOptionsBuilder()
.WithPassword("plain-text-password") // CS0618: Obsolete warning
.Build();
// ✅ Use SecureString instead
var options = new HiveMQClientOptionsBuilder()
.WithPassword(securePassword)
.Build();
X.509 Client Certificates
Client certificates provide strong, certificate-based authentication that's more secure than username/password authentication.
Benefits of Certificate Authentication
- No shared secrets: Private keys never leave the client
- Mutual TLS (mTLS): Both client and broker verify each other's identity
- Revocation support: Certificates can be revoked without changing credentials
- Compliance: Meets enterprise security requirements
Basic Certificate Usage
using System.Security.Cryptography.X509Certificates;
using HiveMQtt.Client;
var options = new HiveMQClientOptionsBuilder()
.WithBroker("your-broker.hivemq.cloud")
.WithPort(8883)
.WithUseTls(true)
.WithClientCertificate("path/to/client-certificate.pem")
.Build();
Multiple Certificates
You can add multiple certificates for certificate chain requirements:
var options = new HiveMQClientOptionsBuilder()
.WithBroker("your-broker.hivemq.cloud")
.WithPort(8883)
.WithUseTls(true)
.WithClientCertificate("path/to/client-cert.pem")
.WithClientCertificate("path/to/intermediate-ca.pem")
.Build();
For detailed certificate configuration, see Use Client Certificates.
Credential Management
Never Hardcode Credentials
// ❌ Never do this
var options = new HiveMQClientOptionsBuilder()
.WithUserName("admin")
.WithPassword("secretpassword123")
.Build();
// ✅ Use environment variables
var options = new HiveMQClientOptionsBuilder()
.WithUserName(Environment.GetEnvironmentVariable("MQTT_USERNAME"))
.WithPassword(GetSecurePasswordFromEnvironment("MQTT_PASSWORD"))
.Build();
Use a Secrets Manager
For production deployments, use a secrets management solution:
// Example with Azure Key Vault
var secretClient = new SecretClient(
new Uri("https://your-vault.vault.azure.net/"),
new DefaultAzureCredential());
var passwordSecret = await secretClient.GetSecretAsync("mqtt-password");
var securePassword = new SecureString();
foreach (char c in passwordSecret.Value.Value)
{
securePassword.AppendChar(c);
}
securePassword.MakeReadOnly();
var options = new HiveMQClientOptionsBuilder()
.WithBroker(configuration["MqttBroker"])
.WithPort(8883)
.WithUseTls(true)
.WithUserName(configuration["MqttUsername"])
.WithPassword(securePassword)
.Build();
Configuration File Security
If using configuration files:
-
Never commit credentials to source control
- Add
appsettings.*.jsonto.gitignore - Use user secrets for development:
dotnet user-secrets
- Add
-
Use environment-specific configurations
// appsettings.Production.json - deployed securely, not in source control
{
"Mqtt": {
"Broker": "production-broker.hivemq.cloud",
"Username": "prod-user"
}
} -
Protect configuration files
- Set appropriate file permissions
- Consider encrypting sensitive sections
Security Checklist
Use this checklist to verify your MQTT client implementation is secure:
Connection Security
- TLS is enabled (
WithUseTls(true)) - Using correct TLS port (typically 8883 for TCP, 8884 for WebSocket)
- Certificate validation is NOT disabled in production
- WebSocket connections use
wss://protocol
Authentication
- Using
SecureStringfor passwords (not plain strings) - Credentials are NOT hardcoded in source code
- Using a secrets manager or secure configuration
- Consider X.509 certificates for enhanced security
Code Practices
- Secrets are not logged or exposed in error messages
- Using environment-specific configurations
- Source control ignores credential files
- Certificate passwords use
SecureString
Deployment
- TLS certificates are valid and not expired
- Using strong authentication (certificates > username/password)
- Broker access is properly firewalled
- Regular credential rotation is in place
Security Resources
HiveMQ Security Documentation
- MQTT Security Fundamentals - Complete series
- TLS/SSL in MQTT
- X.509 Client Certificate Authentication
- Authentication with Username/Password
.NET Security
- SecureString Class - Microsoft Documentation
- X509Certificate2 Class
- .NET User Secrets