پرش به مطلب اصلی

امنیت لایه دوم

در پلتفرم 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 پایان می‌یابند.