{"id":1761,"date":"2025-11-12T23:42:54","date_gmt":"2025-11-12T20:42:54","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/the-sweet-spot-for-speed-and-compatibility-serving-dual-ecdsa-rsa-certificates-on-nginx-and-apache\/"},"modified":"2025-11-12T23:42:54","modified_gmt":"2025-11-12T20:42:54","slug":"the-sweet-spot-for-speed-and-compatibility-serving-dual-ecdsa-rsa-certificates-on-nginx-and-apache","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/en\/the-sweet-spot-for-speed-and-compatibility-serving-dual-ecdsa-rsa-certificates-on-nginx-and-apache\/","title":{"rendered":"The Sweet Spot for Speed and Compatibility: Serving Dual ECDSA + RSA Certificates on Nginx and Apache"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#A_little_story_about_speed_compatibility_and_that_tiny_lock_icon\"><span class=\"toc_number toc_depth_1\">1<\/span> A little story about speed, compatibility, and that tiny lock icon<\/a><\/li><li><a href=\"#Why_serve_both_ECDSA_and_RSA_The_short_honest_answer\"><span class=\"toc_number toc_depth_1\">2<\/span> Why serve both ECDSA and RSA? The short, honest answer<\/a><\/li><li><a href=\"#How_dual-certificate_negotiation_actually_works_without_the_weeds\"><span class=\"toc_number toc_depth_1\">3<\/span> How dual-certificate negotiation actually works (without the weeds)<\/a><\/li><li><a href=\"#Preparing_your_certificates_the_calm_checklist\"><span class=\"toc_number toc_depth_1\">4<\/span> Preparing your certificates: the calm checklist<\/a><ul><li><a href=\"#Two_keys_two_certs_one_identity\"><span class=\"toc_number toc_depth_2\">4.1<\/span> Two keys, two certs, one identity<\/a><\/li><li><a href=\"#Curves_and_key_sizes_that_wont_bite_you_later\"><span class=\"toc_number toc_depth_2\">4.2<\/span> Curves and key sizes that won\u2019t bite you later<\/a><\/li><\/ul><\/li><li><a href=\"#Nginx_dual_certs_done_right_step-by-step\"><span class=\"toc_number toc_depth_1\">5<\/span> Nginx: dual certs done right (step-by-step)<\/a><ul><li><a href=\"#Nginx_server_block_example\"><span class=\"toc_number toc_depth_2\">5.1<\/span> Nginx server block example<\/a><\/li><li><a href=\"#Gotchas_Ive_seen_on_Nginx\"><span class=\"toc_number toc_depth_2\">5.2<\/span> Gotchas I\u2019ve seen on Nginx<\/a><\/li><\/ul><\/li><li><a href=\"#Apache_yes_its_just_as_doable_and_clean\"><span class=\"toc_number toc_depth_1\">6<\/span> Apache: yes, it\u2019s just as doable (and clean)<\/a><ul><li><a href=\"#Apache_vhost_example\"><span class=\"toc_number toc_depth_2\">6.1<\/span> Apache vhost example<\/a><\/li><\/ul><\/li><li><a href=\"#Ciphers_curves_and_the_dont_overthink_it_strategy\"><span class=\"toc_number toc_depth_1\">7<\/span> Ciphers, curves, and the \u201cdon\u2019t overthink it\u201d strategy<\/a><\/li><li><a href=\"#Automation_renew_both_without_ceremony\"><span class=\"toc_number toc_depth_1\">8<\/span> Automation: renew both without ceremony<\/a><\/li><li><a href=\"#Testing_trust_but_verify_and_then_verify_again\"><span class=\"toc_number toc_depth_1\">9<\/span> Testing: trust, but verify (and then verify again)<\/a><ul><li><a href=\"#Quick_client-side_checks\"><span class=\"toc_number toc_depth_2\">9.1<\/span> Quick client-side checks<\/a><\/li><li><a href=\"#Public_scans\"><span class=\"toc_number toc_depth_2\">9.2<\/span> Public scans<\/a><\/li><\/ul><\/li><li><a href=\"#Performance_and_security_polish_the_real-world_bits\"><span class=\"toc_number toc_depth_1\">10<\/span> Performance and security polish (the real-world bits)<\/a><\/li><li><a href=\"#Running_behind_CDNs_or_load_balancers\"><span class=\"toc_number toc_depth_1\">11<\/span> Running behind CDNs or load balancers<\/a><\/li><li><a href=\"#Common_pitfalls_and_how_to_sidestep_them\"><span class=\"toc_number toc_depth_1\">12<\/span> Common pitfalls and how to sidestep them<\/a><\/li><li><a href=\"#Docs_worth_bookmarking\"><span class=\"toc_number toc_depth_1\">13<\/span> Docs worth bookmarking<\/a><\/li><li><a href=\"#A_quick_word_on_HTTP2_and_HTTP3\"><span class=\"toc_number toc_depth_1\">14<\/span> A quick word on HTTP\/2 and HTTP\/3<\/a><\/li><li><a href=\"#Wrapping_it_up_the_calm_fast_compatible_path\"><span class=\"toc_number toc_depth_1\">15<\/span> Wrapping it up: the calm, fast, compatible path<\/a><\/li><\/ul><\/div>\n<h2 id=\"section-1\"><span id=\"A_little_story_about_speed_compatibility_and_that_tiny_lock_icon\">A little story about speed, compatibility, and that tiny lock icon<\/span><\/h2>\n<p>A few years back, a client messaged me late at night with that mix of excitement and worry only a website owner knows. \u201cWe just launched a big landing page, traffic is flowing in, but some older Android devices are seeing SSL errors. And on newer phones, the site feels snappier than usual. Did we do a thing?\u201d We had done a thing. Earlier that day, we switched them to serve <strong>dual ECDSA + RSA certificates<\/strong> on Nginx. Newer devices got the faster ECDSA experience, while older ones quietly fell back to RSA. The best part? No one had to make a choice. The server negotiated. Users just saw a fast, secure site.<\/p>\n<p>Ever had that moment where you want both speed and broad compatibility, but every option feels like a trade-off? That\u2019s where dual certificates shine. In this friendly guide, I\u2019ll walk you through what dual ECDSA + RSA certificates are, why they\u2019re worth your time, and exactly how to set them up on both Nginx and Apache\u2014without turning your evening into a configuration rabbit hole. We\u2019ll talk curves and ciphers in plain language, clean configs you can paste, practical testing tips, and a few gotchas I\u2019ve seen in the wild. Think of it like we\u2019re sitting with coffee and your server\u2019s config open on a second screen. Let\u2019s make that lock icon do more than just sit there.<\/p>\n<h2 id=\"section-2\"><span id=\"Why_serve_both_ECDSA_and_RSA_The_short_honest_answer\">Why serve both ECDSA and RSA? The short, honest answer<\/span><\/h2>\n<p>Here\u2019s the thing: ECDSA and RSA aren\u2019t rivals. They\u2019re more like two different door locks\u2014one newer and lighter, the other older but trusted almost everywhere. ECDSA tends to be <strong>faster and lighter<\/strong> for handshakes, which is especially noticeable on mobile devices. The keys are smaller, the crypto is efficient, and the result is often a little boost in that \u201csite feels snappy\u201d vibe we all chase.<\/p>\n<p>RSA, meanwhile, is the universal adapter. It\u2019s widely compatible, even with older clients that don\u2019t understand ECDSA. If you run a site with any meaningful audience, you probably have visitors using older Android builds, legacy Java runtimes, or embedded devices that are surprisingly picky. Serving an RSA certificate alongside ECDSA lets those folks in without errors\u2014while letting modern browsers take the fast path with ECDSA.<\/p>\n<p>In my experience, the speed gains are real, the compatibility safety net is real, and the setup is not as scary as it sounds. You don\u2019t need to choose. You can have both, and let the TLS handshake pick what\u2019s best for each visitor.<\/p>\n<h2 id=\"section-3\"><span id=\"How_dual-certificate_negotiation_actually_works_without_the_weeds\">How dual-certificate negotiation actually works (without the weeds)<\/span><\/h2>\n<p>When a browser hits your site, there\u2019s a quick back-and-forth where both sides agree on a few things: the TLS version, cipher suites, and the signature algorithm for the certificate. With dual certs installed, your server presents the right certificate for the handshake\u2014ECDSA if the client can handle it, RSA if it can\u2019t. Think of it like offering two keys and the client naturally reaching for the one it knows how to use.<\/p>\n<p>On TLS 1.3, this negotiation is even cleaner and faster. On TLS 1.2, it still works just fine, as long as your server is configured with reasonable ciphers and the certificates are correctly paired with their chains. The real trick is making sure you don\u2019t accidentally mismatch chains, mix intermediates, or feed the server a mystery combo it can\u2019t present coherently. We\u2019ll keep that straight in the setup.<\/p>\n<h2 id=\"section-4\"><span id=\"Preparing_your_certificates_the_calm_checklist\">Preparing your certificates: the calm checklist<\/span><\/h2>\n<h3><span id=\"Two_keys_two_certs_one_identity\">Two keys, two certs, one identity<\/span><\/h3>\n<p>You\u2019ll generate <strong>two private keys<\/strong>: one ECDSA key (usually P-256) and one RSA key (commonly 2048 or 3072 bits). Then you\u2019ll issue two certificates for the same set of hostnames (same CN and SANs). Both certs should represent the same identity, otherwise clients might complain. If you\u2019re using Let\u2019s Encrypt or another ACME provider, most tools can fetch both flavors with a single automation flow.<\/p>\n<p>A small but important detail: the <strong>chain files differ<\/strong>. Your ECDSA certificate will typically be signed by an ECDSA intermediate, and your RSA certificate by an RSA intermediate. Don\u2019t cross the streams\u2014pair each certificate with the correct intermediate chain.<\/p>\n<h3><span id=\"Curves_and_key_sizes_that_wont_bite_you_later\">Curves and key sizes that won\u2019t bite you later<\/span><\/h3>\n<p>If you want to keep things simple and robust, ECDSA P-256 is a safe default. It\u2019s widely supported and fast. P-384 is fine if you have a reason, but P-256 is the smartest starting point. For RSA, 2048-bit is still the pragmatic baseline\u2014big enough to be trustworthy, light enough not to bog down handshakes. I\u2019ve seen folks reach for 4096-bit out of habit, and then wonder why their CPU graph spikes during traffic bursts. Go with 2048 unless your compliance team genuinely requires something larger.<\/p>\n<h2 id=\"section-5\"><span id=\"Nginx_dual_certs_done_right_step-by-step\">Nginx: dual certs done right (step-by-step)<\/span><\/h2>\n<p>I remember the first time I rolled this out on Nginx for a busy WooCommerce store. We deployed in the afternoon lull, watched the graphs, and nothing exploded\u2014which is my favorite metric. Modern Nginx makes this pleasantly straightforward.<\/p>\n<h3><span id=\"Nginx_server_block_example\">Nginx server block example<\/span><\/h3>\n<p>Drop this into your TLS vhost and adjust paths and domains. I\u2019m showing a compact, production-ready pattern that I\u2019ve used on many sites. You can start with this and tweak to taste.<\/p>\n<pre class=\"language-nginx line-numbers\"><code class=\"language-nginx\">server {\n    listen 443 ssl http2;\n    listen [::]:443 ssl http2;\n    server_name example.com www.example.com;\n\n    # Dual certificates: one ECDSA + one RSA\n    ssl_certificate     \/etc\/ssl\/certs\/example-ecdsa-fullchain.pem;\n    ssl_certificate_key \/etc\/ssl\/private\/example-ecdsa.key;\n    ssl_certificate     \/etc\/ssl\/certs\/example-rsa-fullchain.pem;\n    ssl_certificate_key \/etc\/ssl\/private\/example-rsa.key;\n\n    # Protocols and ciphers\n    ssl_protocols TLSv1.2 TLSv1.3;\n    ssl_prefer_server_ciphers off;\n\n    # Prefer modern curves; X25519 is a great choice, with P-256 as a solid fallback\n    ssl_ecdh_curve X25519:P-256;\n\n    # Session settings for speed\n    ssl_session_cache shared:SSL:50m;\n    ssl_session_timeout 1d;\n    ssl_session_tickets off;\n\n    # OCSP stapling (don\u2019t forget to allow outbound DNS + OCSP traffic)\n    ssl_stapling on;\n    ssl_stapling_verify on;\n    resolver 1.1.1.1 1.0.0.1 valid=60s;\n    resolver_timeout 2s;\n\n    # HSTS (enable after you\u2019ve confirmed HTTPS everywhere)\n    add_header Strict-Transport-Security &quot;max-age=63072000; includeSubDomains; preload&quot; always;\n\n    # HTTP\/3 hint (optional, requires QUIC listener elsewhere)\n    add_header Alt-Svc 'h3=&quot;:443&quot;; ma=86400';\n\n    # Root and basic app location\n    root \/var\/www\/example;\n    index index.html index.php;\n\n    location \/ {\n        try_files $uri $uri\/ =404;\n    }\n}\n<\/code><\/pre>\n<p>One thing folks often ask: does the order of the two ssl_certificate lines matter? In practice, Nginx is smart enough to pick the right one based on the client\u2019s handshake. I still like to put the ECDSA pair first, mostly for readability, but you don\u2019t need to obsess over it.<\/p>\n<h3><span id=\"Gotchas_Ive_seen_on_Nginx\">Gotchas I\u2019ve seen on Nginx<\/span><\/h3>\n<p>Don\u2019t mix up your fullchain files. Your ECDSA certificate should be followed by its ECDSA intermediate, and your RSA certificate by its RSA intermediate. If you accidentally pair an ECDSA leaf with an RSA chain, you\u2019ll get quirky errors on certain clients and spend your night with s_client. Also, enable OCSP stapling only if your server can reach the OCSP responders; otherwise, you slow down handshakes for no benefit. And after a renewal, use a graceful reload so Nginx picks up the new files without dropping connections.<\/p>\n<p>If you enjoy tightening TLS on Nginx, you might also like how I lock down access to admin panels with client certs; I shared a calm, step-by-step approach in <a href=\"https:\/\/www.dchost.com\/blog\/en\/yonetim-panellerini-mtls-ile-nasil-kale-gibi-korursun-nginxte-istemci-sertifikalari-adim-adim\/\">protecting panels with mTLS on Nginx<\/a>. Different use case, same love for clean TLS setups.<\/p>\n<h2 id=\"section-6\"><span id=\"Apache_yes_its_just_as_doable_and_clean\">Apache: yes, it\u2019s just as doable (and clean)<\/span><\/h2>\n<p>Apache has supported this pattern for a while, and it\u2019s pleasantly readable in a vhost. The main idea mirrors Nginx: define both certificate + key pairs, let the server present the right one at handshake time, and keep your protocols lean.<\/p>\n<h3><span id=\"Apache_vhost_example\">Apache vhost example<\/span><\/h3>\n<pre class=\"language-apache line-numbers\"><code class=\"language-apache\">&lt;VirtualHost *:443&gt;\n    ServerName example.com\n    ServerAlias www.example.com\n\n    # Dual certificates: ECDSA + RSA\n    SSLEngine on\n    SSLCertificateFile    \/etc\/ssl\/certs\/example-ecdsa-fullchain.pem\n    SSLCertificateKeyFile \/etc\/ssl\/private\/example-ecdsa.key\n    SSLCertificateFile    \/etc\/ssl\/certs\/example-rsa-fullchain.pem\n    SSLCertificateKeyFile \/etc\/ssl\/private\/example-rsa.key\n\n    # Protocols\n    SSLProtocol TLSv1.2 TLSv1.3\n\n    # Modern curves and sane ciphers\n    SSLOpenSSLConfCmd Curves X25519:P-256\n    SSLHonorCipherOrder off\n\n    # Stapling\n    SSLUseStapling on\n    SSLStaplingResponderTimeout 5\n    SSLStaplingReturnResponderErrors off\n    SSLStaplingCache shmcb:\/var\/run\/ocsp(128000)\n\n    # HSTS (enable after confirming HTTPS-only)\n    Header always set Strict-Transport-Security &quot;max-age=63072000; includeSubDomains; preload&quot;\n\n    DocumentRoot \/var\/www\/example\n\n    &lt;Directory \/var\/www\/example&gt;\n        AllowOverride All\n        Require all granted\n    &lt;\/Directory&gt;\n&lt;\/VirtualHost&gt;\n<\/code><\/pre>\n<p>I once inherited a config where the admin had put the ECDSA key under the RSA certificate line (and vice versa). It produced the kind of errors that only show up for certain devices, which makes debugging a special treat. Double-check your pairs. Keep your chain files tidy. And if you\u2019re using older Apache, make sure you\u2019re on a version that supports multiple SSLCertificateFile directives in the same vhost for different key types\u2014most modern 2.4 builds do, but if you\u2019re stuck on something ancient, it\u2019s time for a peaceful upgrade.<\/p>\n<h2 id=\"section-7\"><span id=\"Ciphers_curves_and_the_dont_overthink_it_strategy\">Ciphers, curves, and the \u201cdon\u2019t overthink it\u201d strategy<\/span><\/h2>\n<p>I know it\u2019s tempting to fall down the rabbit hole of perfect cipher lists, but here\u2019s the friendly advice: <strong>favor TLS 1.3<\/strong> and support TLS 1.2 for compatibility; prefer X25519 and P-256 curves; and don\u2019t enforce a rigid cipher order unless you have a clear need. TLS 1.3 simplifies a lot of the old complexity. For TLS 1.2, make sure ECDSA-capable suites are available so modern clients happily choose them, while legacy clients still find a familiar RSA path.<\/p>\n<p>Chacha20-Poly1305 support is great for mobile devices without AES acceleration, and AES-GCM is excellent on servers with hardware offload. The beautiful part: the client and server usually figure this out together without you micro-managing it.<\/p>\n<h2 id=\"section-8\"><span id=\"Automation_renew_both_without_ceremony\">Automation: renew both without ceremony<\/span><\/h2>\n<p>The first time I set this up with manual cert issuance, I promised myself I\u2019d never do that again. ACME tools like Certbot or acme.sh can request <strong>both ECDSA and RSA<\/strong> variants with the same hostnames, save them to predictable paths, and run a reload hook to pick them up\u2014no drama, no waking up at 3 a.m. because a cert expired. Whichever tool you choose, aim for three things: consistent file paths, separate key files per algorithm, and a reload that doesn\u2019t drop connections.<\/p>\n<p>On Nginx, <code>nginx -s reload<\/code> keeps things smooth. On Apache, <code>apachectl graceful<\/code> is your friend. I like to log the reload outcome and send it to whatever monitoring I\u2019m using. If there\u2019s a typo or missing file, I\u2019d rather find out now than during peak traffic.<\/p>\n<h2 id=\"section-9\"><span id=\"Testing_trust_but_verify_and_then_verify_again\">Testing: trust, but verify (and then verify again)<\/span><\/h2>\n<p>There\u2019s a little ritual I do after deploying dual certs. First, I use OpenSSL to confirm the server offers what I think it offers. Then I run a public test to see what the broader world sees. Finally, I check a couple of older devices or Java runtimes to confirm there\u2019s no surprise breakage.<\/p>\n<h3><span id=\"Quick_client-side_checks\">Quick client-side checks<\/span><\/h3>\n<p>Check that ECDSA is presented to a modern client:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">openssl s_client -connect example.com:443 -servername example.com -tls1_3 \n  -sigalgs ECDSA+SHA256 -brief<\/code><\/pre>\n<p>And sanity-check RSA fallback by simulating a client that prefers RSA signatures:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">openssl s_client -connect example.com:443 -servername example.com -tls1_2 \n  -sigalgs RSA+SHA256 -brief<\/code><\/pre>\n<p>If both handshakes succeed and you see the matching certificate chains, you\u2019re in good shape. I also like to test curve negotiation quickly:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">openssl s_client -connect example.com:443 -servername example.com -tls1_3 -curves X25519<\/code><\/pre>\n<h3><span id=\"Public_scans\">Public scans<\/span><\/h3>\n<p>After the local checks, I run a public scan to confirm the world sees both cert types and no odd chain issues. The classic way to do this is with <a href=\"https:\/\/www.ssllabs.com\/ssltest\/\" rel=\"nofollow noopener\" target=\"_blank\">the SSL Labs server test<\/a>. It\u2019s free, and I\u2019ve caught weirdities I wouldn\u2019t have noticed otherwise\u2014like a forgotten intermediate on a secondary host, or a firewall blocking OCSP.<\/p>\n<h2 id=\"section-10\"><span id=\"Performance_and_security_polish_the_real-world_bits\">Performance and security polish (the real-world bits)<\/span><\/h2>\n<p>I like to view TLS as part of the whole delivery pipeline. You don\u2019t just want a green padlock; you want a lock that opens instantly and a server that stays cool under traffic. A few practical touches help a lot. Session resumption keeps repeat visitors snappy. Stapling removes a slow validation step from the visitor\u2019s side. HSTS encourages browsers to skip the HTTP-to-HTTPS dance once they\u2019ve seen your site is serious about encryption.<\/p>\n<p>On busy nodes, watch CPU and handshake counts after enabling dual certs, not because it\u2019s likely to spike, but because visibility is sanity. I once tuned a WooCommerce setup where a 4096-bit RSA certificate was quietly adding load. Switching to 2048-bit RSA and keeping ECDSA P-256 made the handshake cost drop without changing any other knobs. Sometimes it\u2019s the simple switches that count.<\/p>\n<h2 id=\"section-11\"><span id=\"Running_behind_CDNs_or_load_balancers\">Running behind CDNs or load balancers<\/span><\/h2>\n<p>If you terminate TLS on your own Nginx or Apache (even behind a load balancer), dual certs are still your friend. If your CDN terminates TLS for you, then the CDN\u2019s edge is responsible for picking the certificate algorithm. In that case, you might still choose to serve ECDSA at the edge for speed and keep RSA as a fallback for compatibility, while the origin is protected with something simpler. If your load balancer supports TLS passthrough to your Nginx or Apache, you can still present dual certs at the application layer\u2014just make sure SNI and ALPN flow through cleanly.<\/p>\n<p>What matters is aligning your strategy: where is TLS actually terminating, and who is presenting certificates to the visitor? If that answer changes, your dual-cert plan might move one layer up, but the idea remains the same: give modern clients the faster ECDSA experience, without locking out the long tail of legacy devices.<\/p>\n<h2 id=\"section-12\"><span id=\"Common_pitfalls_and_how_to_sidestep_them\">Common pitfalls and how to sidestep them<\/span><\/h2>\n<p>First: mismatched chains. This is the classic footgun. Keep each certificate paired with its correct intermediate. Second: overzealous cipher pruning. It\u2019s easy to get carried away and accidentally remove something an older but still important client needs. Third: forgetting that some firewalls block OCSP. If stapling fails on the server side, handshakes can stall or slow down for clients doing their own checks. Fourth: reloads that never happen. If you automate renewals, automate the reload right after\u2014and log the result.<\/p>\n<p>One more I\u2019ve seen: deploying ECDSA on a staging domain but forgetting RSA entirely, then flipping to production. Everything works fine in your modern browser tests, but your customer support queue hears from users on legacy platforms. Dual certs are only a win if both are truly there.<\/p>\n<h2 id=\"section-13\"><span id=\"Docs_worth_bookmarking\">Docs worth bookmarking<\/span><\/h2>\n<p>When I want to sanity-check a directive or refresh a nuance, I keep a couple of links handy. The Nginx SSL module page is great for a quick read on certificate directives, like <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_ssl_module.html#ssl_certificate\" rel=\"nofollow noopener\" target=\"_blank\">ssl_certificate in the Nginx docs<\/a>. On the Apache side, the mod_ssl docs are the gold standard\u2014start at <a href=\"https:\/\/httpd.apache.org\/docs\/2.4\/mod\/mod_ssl.html\" rel=\"nofollow noopener\" target=\"_blank\">mod_ssl on the Apache docs<\/a> and scroll to the certificate and protocol areas. And when I want a public view of how the world sees my server, I run the <a href=\"https:\/\/www.ssllabs.com\/ssltest\/\" rel=\"nofollow noopener\" target=\"_blank\">SSL Labs test<\/a> again. These three cover me 99% of the time.<\/p>\n<h2 id=\"section-14\"><span id=\"A_quick_word_on_HTTP2_and_HTTP3\">A quick word on HTTP\/2 and HTTP\/3<\/span><\/h2>\n<p>Serving dual ECDSA + RSA certificates plays nicely with both HTTP\/2 and HTTP\/3. These protocols sit on top of TLS in slightly different ways, but the certificate negotiation is compatible with how they choose ciphers and curves. If you\u2019re enabling HTTP\/3, just remember it typically uses a separate QUIC listener; your certificate configuration applies there too. And if you ever debug quirky HTTP\/2 or keep-alive behavior, it\u2019s rarely the certificate\u2014timeouts, ALPN, and queueing are usually the real culprits. Been there, fixed that.<\/p>\n<h2 id=\"section-15\"><span id=\"Wrapping_it_up_the_calm_fast_compatible_path\">Wrapping it up: the calm, fast, compatible path<\/span><\/h2>\n<p>When I look back at all the TLS changes over the years, dual ECDSA + RSA is one of those rare upgrades that feels like getting dessert without sacrificing dinner. Modern clients get a handshake that\u2019s lean and quick. Legacy clients get a handshake they understand. You avoid the stress of \u201ceither-or\u201d decisions, and your ops life gets a little calmer.<\/p>\n<p>If you\u2019re setting this up today, here\u2019s the short recipe: generate an ECDSA P-256 key and a 2048-bit RSA key, issue two certificates with the same SAN set, pair each with the correct chain, and plug them into your Nginx or Apache vhost. Keep TLS 1.3 on, support TLS 1.2, let the curves be modern, staple OCSP if your network allows it, and automate renewals with a graceful reload. Then test with OpenSSL and a public scanner so you sleep well.<\/p>\n<p>That\u2019s it. You don\u2019t need to wrestle with endless cipher lists or chase obscure tweaks. Start with a clean, dual-cert setup, watch your logs, and iterate only if you see a real reason. Hope this was helpful! If you want more TLS tinkering ideas, check out the mTLS article above, and I\u2019ll see you in the next post, hopefully with a cup of coffee and fewer red alerts.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>\u0130&ccedil;indekiler1 A little story about speed, compatibility, and that tiny lock icon2 Why serve both ECDSA and RSA? The short, honest answer3 How dual-certificate negotiation actually works (without the weeds)4 Preparing your certificates: the calm checklist4.1 Two keys, two certs, one identity4.2 Curves and key sizes that won\u2019t bite you later5 Nginx: dual certs done [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1762,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-1761","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/1761","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/comments?post=1761"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/1761\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media\/1762"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media?parent=1761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/categories?post=1761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/tags?post=1761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}