بازگشت به وبلاگ

چرا RSA را کنار گذاشتیم و به Ed25519 روی آوردیم (شما هم باید همین کار را بکنید)

TLS خودمیزبان به کلیدهای RSA 4096 بیتی نیاز ندارد. دلیل تغییر Bedrud به Ed25519 و معنای آن برای گواهی‌نامه‌های خودامضای شما.

۲۲ اردیبهشت ۱۴۰۵ تیم Bedrud engineering, security, self-hosting

هشدار مرورگر را دیده‌اید. «اتصال شما خصوصی نیست.» گواهی‌نامه‌های خودامضا وقتی خودتان هاست می‌کنید، واقعیتی اجتناب‌ناپذیرند. اما کلید داخل آن گواهی‌نامه مهم‌تر از چیزی است که فکر می‌کنید — و اکثر آموزش‌ها هنوز پیش‌فرض اشتباهی را پیشنهاد می‌دهند.

عادت RSA

هر راهنمای خودمیزبانی در اینترنت یک چیز می‌گوید:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

RSA 4096. چون عدد بزرگ‌تر یعنی امنیت بیشتر، درست است؟ دیگر نه. کلیدهای RSA 4096 حجمشان 3.2 کیلوبایت است. روی یک VPS 5 دلاری تولیدشان ثانیه‌ها طول می‌کشد. و سطح امنیتی‌ای ارائه می‌دهند که تقریباً معادل یک کلید منحنی بیضی 256 بیتی است.

RSA پیش‌فرض است به دلیل اینرسی تاریخی، نه برتری فنی. همه‌جا کار می‌کند و برای گواهی‌نامه‌های صادرشده توسط CA عمومی، این سازگاری هنوز اهمیت دارد. اما برای گواهی‌نامه‌های خودامضا در استکی که خودتان کنترل می‌کنید؟ شما دارید مالیات عملکردی برای سازگاری‌ای که نیاز ندارید می‌پردازید.

Ed25519 در یک نگاه

Ed25519 یک طرح امضای EdDSA ساخته‌شده روی Curve25519 است. کلیدهای 256 بیتی با اندازه ثابت تولید می‌کند. منحصراً برای امضای دیجیتال طراحی شده — بدون رمزگذاری، بدون تبادل کلید، فقط امضا. این تمرکز آن را ساده‌تر، سریع‌تر و کمتر مستعد خطای پیکربندی می‌کند.

در Go یک شهروند درجه یک است. بسته crypto/ed25519 از Go 1.13 در کتابخانه استاندارد است. تولید کلید دو خط است. سریالایز با x509.MarshalPKCS8PrivateKey انجام می‌شود. بدون وابستگی خارجی، بدون CGo، بدون تگ build خاص.

مقایسه سه‌جانبه

جنبهRSA 4096 / 2048ECDSA P-256Ed25519
امنیت~112–128 بیت. بالغ، خوب مطالعه‌شده.~128 بیت. منحنی NIST.~128 بیت. طراحی‌شده برای مقاومت در برابر حملات کانال جانبی.
عملکردکندترین. عملیات اعداد بزرگ.تأیید ~10 برابر سریع‌تر از RSA.سریع‌ترین. 30k+ امضا/ثانیه در Go. کلیدهای بسیار کوچک.
اندازه کلید2048 یا 4096 بیت. بزرگ روی دیسک.256 بیت. فشرده.256 بیت ثابت. کمترین فضای اشغال‌شده.
سازگاریهمگانی. همه‌جا کار می‌کند.خوب. تمام مرورگرها/کلاینت‌های مدرن.در حال رشد. پشتیبانی کامل در Go، SSH، TLS مدرن.
قالباستاندارد PKCS#8.PKCS#8 روی SEC1.PKCS#8 بومی.
عمر کلیدنیاز به چرخش مکررتر.طولانی‌تر قابل قبول.مشابه سایر منحنی‌های EC.
سادگی در Goپشتیبانی کامل x509.خطر باگ KeyEncipherment (زیر را ببینید).خالص. بدون گزینه رمزگذاری.

منابع: انواع کلید توضیح داده‌شده، بنچمارک‌های Go: RSA vs ECDSA vs Ed25519، مقایسه الگوریتم‌های کلید SSH

تله ECDSA KeyUsage

باگی وجود دارد که تقریباً هر کسی که از RSA به ECDSA مهاجرت می‌کند، در آن می‌افتد. در بسته crypto/x509 در Go، کلیدهای RSA هم به KeyUsageDigitalSignature و هم به KeyUsageKeyEncipherment در قالب گواهی‌نامه نیاز دارند. اگر این الگو را برای ECDSA کپی کنید — KeyUsageKeyEncipherment را به کلید EC اضافه کنید — برخی کلاینت‌های TLS گواهی‌نامه را رد می‌کنند. کلیدهای EC رمزگذاری کلید انجام نمی‌دهند. این پسوند بی‌معنی و فعالاً مضر است.

رفع مشکل در تولید گواهی‌نامه Bedrud (server/internal/utils/tls.go) این‌گونه است:

func keyUsageForAlgo(algo KeyAlgorithm) x509.KeyUsage {
    switch algo {
    case KeyRSA2048, KeyRSA4096:
        return x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment
    default:
        return x509.KeyUsageDigitalSignature
    }
}

Ed25519 در شاخه پیش‌فرض قرار می‌گیرد. امضای دیجیتال خالص. هیچ گزینه KeyEncipherment برای پیکربندی اشتباه وجود ندارد. یک تله کمتر.

معنای آن روی VPS 5 دلاری

روی Hetzner CX22 (2 vCPU، 4 GB RAM)، تفاوت قابل اندازه‌گیری است:

  • تولید کلید: RSA 4096 حدود 1–2 ثانیه طول می‌کشد. Ed25519 کمتر از 1 میلی‌ثانیه. وقتی سرور شما در اولین بوت گواهی‌نامه خودامضا تولید می‌کند، این مهم است.
  • دست دادن TLS: Ed25519 سریع‌تر امضا و تأیید می‌کند و تأخیر handshake را کاهش می‌دهد. روی سروری که ده‌ها اتصال WebRTC را مدیریت می‌کند، این میلی‌ثانیه‌ها تجمع پیدا می‌کنند.
  • فضای دیسک: کلید خصوصی Ed25519 در PEM 48 بایت است. کلید RSA 4096 حدود 3.2 کیلوبایت. برای یک گواهی‌نامه تفاوت زیادی نیست، اما اختلاف وزن محاسباتی را منعکس می‌کند.

کاری که Bedrud انجام می‌دهد

Bedrud به‌طور پیش‌فرض گواهی‌نامه‌های خودامضای Ed25519 تولید می‌کند. تابع GenerateSelfSignedCert از KeyEd25519 استفاده می‌کند مگر اینکه چیز دیگری مشخص کنید.

اگر به الگوریتم متفاوتی نیاز دارید — برای سازگاری کلاینت‌های قدیمی یا سیاست‌های داخلی — از پرچم --key-algorithm استفاده کنید:

bedrud run --key-algorithm rsa4096
bedrud run --key-algorithm ecdsa256

مقادیر پشتیبانی‌شده: ed25519 (پیش‌فرض)، ecdsa256، rsa2048، rsa4096.

چه زمانی به RSA پایبند باشید

RSA نمرده است. هنوز برای این موارد لازم است:

  • کلاینت‌های قدیمی Java که handshake TLS با Ed25519 را پشتیبانی نمی‌کنند
  • دستگاه‌های Android قبل از 7.0 (Nougat) که پشتیبانی Ed25519 در پشته TLS ندارند
  • دستگاه‌های تعبیه‌شده با نسخه‌های قدیمی OpenSSL یا mbedTLS
  • محیط‌های سازمانی با middleboxهای بازرسی TLS که فقط RSA را می‌فهمند

اگر استک شما مدرن است — باک‌اند Go، مرورگرهای مبتنی بر Chromium، اپ‌های موبایل اخیر — Ed25519 همه‌جایی که اهمیت دارد کار می‌کند.

حرف آخر

زیرساخت خودمیزبان نباید کلیدهای RSA 4096 بیتی را به خاطر توصیه یک آموزش سال 2013 به دوش بکشد. Ed25519 سریع‌تر، کوچک‌تر و کمتر مستعد خطاست. کتابخانه استاندارد Go برای آن بهینه‌شده است. و برای گواهی‌نامه‌های خودامضا در یک استک کنترل‌شده، استدلال سازگاری RSA قابل دفاع نیست.

خودمیزبانی با پیش‌فرض‌های بهتر. Bedrud را نصب کنید و خودتان امتحان کنید.