امنیت لایه دوم
در پلتفرم AirNgin امنیت ارتباط بین دستگاهها و سرور تنها به TLS یا امنیت سطح شبکه محدود نمیشود. ما یک لایه امنیتی دوم در سطح اپلیکیشن (Application Layer Encryption) پیادهسازی کردهایم تا حتی اگر مهاجم به بستههای MQTT دسترسی پیدا کند، امکان خواندن یا دستکاری دادهها را نداشته باشد.
توجه داشته باشید که استفاده از این لایه امنیتی الزامی نیست. شما تولیدکنندگان محترم میتوانید بر اساس نیازهای محصول و کاربران خود، در صورت تمایل این قابلیت را در دستگاههای خود فعال کنید.
استفاده از این خدمت برای کاربران شما شامل هزینه است و بر اساس قوانین پلتفرم، مبلغ مربوطه بهصورت خودکار از حساب کاربر شما کسر خواهد شد.
این مکانیزم، رمزنگاری AES-256-GCM را برای هر پیام MQTT اعمال میکند و باعث میشود تمام پیامها بهصورت امن و غیرقابلتقلب تبادل شوند.
چرا امنیت لایه دوم ضروری است؟
حتی در شرایط دارای TLS نیز ممکن است:
-
دستگاهها در شبکههای محلی (LAN) یا بدون TLS کار کنند (پورت 1883)
-
برخی تولیدکنندگان نیاز به ارتباط سبک وزن بدون TLS داشته باشند
-
حملات MITM در لایه شبکه یا واسطهای محلی اتفاق بیفتد
بنابراین AirNgin لایه دوم امنیت را در خود پیام MQTT قرار داده تا امنیت End-to-End برقرار شود.
ساختار امنیت لایه دوم AirNgin
کلید اختصاصی برای هر دستگاه
هر دستگاه در AirNgin یک Device Secret کاملاً یکتا دارد. این کلید پایه تمام عملیات رمزنگاری است.
رمزنگاریِ پیامها با AES-256-GCM
ویژگیهای AES-GCM استفاده شده در AirNgin:
-
محرمانگی (Confidentiality)
-
صحت پیام (Integrity)
-
جلوگیری از دستکاری (Tamper-Proofing)
-
غیرقابل بازپخش بودن پیامها (Anti-Replay)
ساختار پیام رمزنگاری شده :
{
"ciphertext": "base64",
"tag": "base64",
"nonce": "base64",
"version": "string",
"timestamp": long,
"deviceSerial": "string",
"more": "string"
}
ciphertext
نوع: Base64 String
حاوی داده رمزشده اصلی است که بهوسیله AES-256-GCM رمزگذاری شده است. محتوای plaintext شامل پارامترهای کاربردی مثل دادههای سنسورها، فرمانها یا وضعیت دستگاه است. این داده بدون کلید اختصاصی دستگاه قابل رمزگشایی نیست.
tag
نوع: Base64 String
Authentication Tag مربوط به AES-GCM است. این مقدار تضمین میکند که پیام دستکاری نشده و معتبر است. هرگونه تغییر در داده (حتی یک بیت) باعث نامعتبر شدن tag میشود و پیام توسط سرور رد میگردد.
nonce
نوع: Base64 String
یک مقدار یکتا و تصادفی برای هر پیام است که برای جلوگیری از Replay Attack استفاده میشود. هیچ پیامی با nonce تکراری پذیرفته نمیشود.
version
نوع: String
مثال: "v1" نسخه پروتکل رمزنگاری. در آینده امکان ارتقای الگوریتم، ساختار پیام یا استانداردها وجود دارد. این فیلد تضمین میکند هر کلاینت و سرور بداند فرمت پیام مطابق کدام نسخه است.
timestamp
نوع: عدد Long (Unix Time)
زمان ارسال پیام بهصورت یونیکستایم. سرور از این مقدار برای:
جلوگیری از Replay Attack
اعتبارسنجی تازگی پیام
مدیریت پیامهای out-of-order
استفاده میکند.
پیامهایی که خارج از بازه زمانی قابل قبول باشند، رد خواهند شد.
deviceSerial
نوع: String
شمارهسریال یکتا دستگاه.
more
نوع: String
فضایی برای دادههای جانبی و متادیتا که در نسخههای آینده یا برای ویژگیهای سفارشی استفاده میشود. این فیلد ممکن است شامل اطلاعاتی مثل نوع پیام، وضعیت داخلی، یا ساختارهای توسعهیافته باشد.
فرآیند Encryption / Decryption در یک نگاه
🔸 سمت دستگاه (ESP / STM32 / ESP32)
تولید nonce → random(12 bytes)
ساخت JSON پیام
رمزنگاری با AES-256-GCM
ارسال در قالب تعریف شده در MQTT
🔸 سمت سرور (C# .NET)
دریافت پیام MQTT
استخراج nonce + cipher + tag
رمزگشایی با DeviceSecret
اعتبارسنجی Tag و Timestamp
پردازش پیام
تاپیک ها
زمانی که دستگاه یا تولیدکننده از امنیت لایه دوم AES استفاده میکند، ساختار تاپیکهای MQTT نیز برای تشخیص پیامهای رمزنگاریشده تغییر میکند.
تاپیکهایی که دستگاه روی آنها Publish میکند
هر پیامی که با امنیت لایه دوم ارسال شود، باید در تاپیک مربوطه با پسوند زیر منتشر شود:
/AES
تاپیکهایی که دستگاه روی آنها Subscribe میکند
برای دریافت پیامهای رمزنگاریشده از سرور، تاپیکهایی که دستگاه گوش میدهد نیز بهصورت زیر هستند:
.../AES
بنابراین تمام پیامهای رمزنگاریشده در لایه دوم دارای تاپیکهایی هستند که به صورت مشخص و استاندارد با /AES پایان مییابند.