سال ۲۰۲۵ است و دیگر نمیتوان امنیت را به تعویق انداخت. در دنیای هوش مصنوعی، کلیدهای API، بردارهای embedding، پرامپتهای حساس و دادههای کاربران همه روزه در معرض خطر هستند. خوشبختانه .NET 10 با اضافه کردن اولین الگوریتمهای استاندارد پساکوانتومی (Post-Quantum Cryptography) مستقیماً در BCL، ابزارهای قدرتمندی در اختیار ما قرار داده است.
در این مقاله به صورت عملی و بدون پیچیدگیهای غیرضروری یاد میگیریم که چطور از دو ابزار اصلی جدید استفاده کنیم:
- ML-DSA (قبلاً Dilithium): امضای دیجیتال مقاوم در برابر کامپیوترهای کوانتومی
- AES-GCM: رمزنگاری احراز هویتشده (Authenticated Encryption) که همچنان بهترین انتخاب برای حفاظت از اسرار است
هدف این است که در پایان مقاله بتوانید کلیدهای OpenAI، embeddingهای حساس و هر داده محرمانه دیگری را به شکل امن و آیندهنگرانه ذخیره و استفاده کنید.
۱. امضای پساکوانتومی با ML-DSA
چرا باید نگران کوانتوم باشیم؟
الگوریتم شُور (Shor’s algorithm) روی کامپیوتر کوانتومی میتواند RSA و ECDSA را در چند دقیقه بشکند. حمله «Harvest Now, Decrypt Later» یعنی دشمن امروز دادههای امضاشده شما را جمعآوری میکند و سالها بعد آنها را میشکند. پس اگر دادهای دارید که باید ۱۰ سال دیگر هم معتبر باشد، همین امروز باید به ML-DSA مهاجرت کنید.
استفاده بسیار ساده از ML-DSA در .NET 10
using System.Security.Cryptography;
using System.Text;
// بررسی پشتیبانی پلتفرم
if (!MLDsa.IsSupported)
throw new PlatformNotSupportedException("ML-DSA در این سیستم پشتیبانی نمیشود");
// تولید جفتکلید ML-DSA-65 (تقریباً معادل امنیت ۱۹۲ بیت)
using var mlDsa = MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa65);
// صادرات کلید عمومی (برای بهاشتراکگذاری)
byte[] publicKey = mlDsa.ExportSubjectPublicKeyInfo();
Console.WriteLine($"اندازه کلید عمومی: {publicKey.Length} بایت");
// متن دلخواه برای امضا
string message = "این یک پیام بسیار مهم است که باید تا سال ۲۰۴۰ معتبر بماند.";
byte[] data = Encoding.UTF8.GetBytes(message);
// امضا کردن
byte[] signature = mlDsa.SignData(data);
Console.WriteLine($"اندازه امضا: {signature.Length} بایت (~3.3 KB برای ML-DSA-65)");
// ——— مرحله تأیید ———
using var verifier = MLDsa.ImportSubjectPublicKeyInfo(publicKey);
bool valid = verifier.VerifyData(data, signature);
Console.WriteLine($"امضا معتبر است؟ {valid}"); // True
// تست دستکاری
data[0] ^= 1; // یک بیت را عوض میکنیم
bool tampered = verifier.VerifyData(data, signature);
Console.WriteLine($"امضا پس از دستکاری معتبر است؟ {tampered}"); // Falseنکات مهم عملی
- اندازه امضا بزرگ است (۲٫۴ تا ۴٫۶ کیلوبایت بسته به سطح امنیتی). این «مالیات کوانتومی» است و باید در طراحی پروتکل در نظر گرفته شود.
- API دقیقاً مشابه RSA و ECDsa است: مهاجرت بسیار ساده است.
- سه سطح امنیتی داریم: MLDsa44 (۱۲۸ بیت)، MLDsa65 (۱۹۲ بیت، توصیهشده)، MLDsa87 (۲۵۶ بیت).
۲. رمزنگاری احراز هویتشده با AES-GCM
برای حفاظت از کلیدهای API، توکنها و embeddingها هیچ چیز بهتر و سادهتر از AES-GCM نیست. این الگوریتم هم محرمانگی و هم یکپارچگی (integrity) را تضمین میکند.
using System.Security.Cryptography;
using System.Text;
// کلید اصلی (در دنیای واقعی از Key Vault یا HSM بگیرید)
byte[] masterKey = RandomNumberGenerator.GetBytes(32); // 256 بیت
string secret = "sk-proj-SuperSecretOpenAIKey1234567890";
byte[] plaintext = Encoding.UTF8.GetBytes(secret);
// ——— رمزنگاری ———
byte[] nonce = RandomNumberGenerator.GetBytes(12); // هر بار باید یکتا باشد!
byte[] ciphertext = new byte[plaintext.Length];
byte[] tag = new byte[16]; // تگ احراز هویت
using var aes = new AesGcm(masterKey);
aes.Encrypt(nonce, plaintext, ciphertext, tag);
// ذخیرهسازی: nonce + ciphertext + tag را کنار هم نگه دارید
byte[] stored = nonce.Concat(ciphertext).Concat(tag).ToArray();
// ——— رمزگشایی ———
static string Decrypt(byte[] masterKey, byte[] storedData)
{
var nonce = storedData.AsSpan(0, 12);
var tag = storedData.AsSpan(storedData.Length - 16);
var ciphertext = storedData.AsSpan(12, storedData.Length - 28);
using var aes = new AesGcm(masterKey);
byte[] recovered = new byte[ciphertext.Length];
aes.Decrypt(nonce, ciphertext, tag, recovered);
return Encoding.UTF8.GetString(recovered);
}
// استفاده
string apiKey = Decrypt(masterKey, stored);
Console.WriteLine(apiKey); // کلید اصلی برمیگردد
// تست دستکاری → به طور خودکار خطا میدهد
ciphertext[0] ^= 1;
try { Decrypt(masterKey, stored); }
catch (CryptographicException) { Console.WriteLine("دستکاری تشخیص داده شد!"); }نکات طلایی
- هرگز nonce را تکرار نکنید (۱۲ بایت تصادفی کافی است).
- کلید اصلی (masterKey) را هرگز در کد سخت نکنید. از Azure Key Vault، AWS Secrets Manager یا فایل رمز شده با دسترسی 600 استفاده کنید.
- پس از استفاده از کلید، آرایه بایت را با Array.Clear پاک کنید (برای stringها نمیشود پاک کرد، پس بهتر است تا حد امکان با byte[] کار کنید).
۳. کاربردهای واقعی در پروژههای هوش مصنوعی
الف. حفاظت از کلیدهای OpenAI و مدلهای دیگر
// بارگذاری کلید رمز شده از دیسک
byte[] encryptedKey = File.ReadAllBytes(".openai/key.enc");
string apiKey = Decrypt(masterKey, encryptedKey);
// استفاده موقت
OpenAiClient client = new(apiKey);
// ... استفاده ...
// پاک کردن از حافظه
Array.Clear(Encoding.UTF8.GetBytes(apiKey), 0, apiKey.Length);
ب. حفاظت از بردارهای embedding (در صورت لزوم)
توجه: رمزنگاری embeddingها باعث میشود جستجوی شباهت (k-NN) مستقیماً ممکن نباشد. دو راه حل عملی وجود دارد:
- embeddingها را در دیتابیس امن (شبکه خصوصی + RBAC + دیسک رمز شده) به صورت plaintext نگه دارید؛ راهکار اکثر شرکتها در ۲۰۲۵.
- فقط در زمان ذخیرهسازی طولانیمدت (بکآپ سرد) آنها را با AES-GCM رمز کنید.
چکلیست امنیتی سریع قبل از استقرار
- آیا از ML-DSA یا حداقل RSA-3072+ برای امضاهای بلندمدت استفاده میکنید؟
- آیا همه اسرار (API Key، Connection String و غیره) با AES-256-GCM رمز شدهاند؟
- آیا nonceها یکتا و تصادفی هستند؟
- آیا کلیدهای اصلی از Key Vault یا HSM بارگذاری میشوند؟
- آیا ورودی کاربر قبل از ارسال به LLM اعتبارسنجی میشود؟ (حداقل فیلتر کلمات کلیدی مثل "ignore previous instructions")
- آیا هیچ وقت کلید یا داده حساسی لاگ نمیشود؟
نتیجهگیری
.NET 10 با آوردن ML-DSA و ML-KEM مستقیماً در BCL، یکی از سادهترین و امنترین پلتفرمها برای ساخت برنامههای پساکوانتومی شده است. دیگر نیازی به کتابخانههای خارجی یا پیچیدگیهای زیاد نیست. امنیت دیگر یک «ویژگی اضافه» نیست؛ پایه و اساس هر برنامه هوش مصنوعی موفق است.
از امروز شروع کنید: یک کلید ML-DSA بسازید، کلیدهای API خود را با AES-GCM رمز کنید و خیالتان راحت باشد که حتی اگر کامپیوترهای کوانتومی ۱۰ سال دیگر آمدند، دادههای شما همچنان امن خواهند ماند.