eMudhra की कमज़ोर CA कुंजियाँ: PKI के 5 मिथक टूटे
एक भरोसेमंद CA ने ऐसी प्राइवेट कुंजियाँ भेजीं जो मिलीसेकंड में टूट जाती हैं। eMudhra की घटना से PKI, key generation और ऑडिट की पाँच मान्यताएँ परखते हैं।

eMudhra की एक certificate authority की प्राइवेट कुंजी संख्या 4 है। कोई 384-bit की संख्या नहीं जो 4 से शुरू होती हो — बस 4, जिसे सम्मानजनक दिखाने के लिए 47 ज़ीरो बाइट्स से भरा गया है। यह CA key generation की ऐसी विफलता है जिसे मैं असंभव मानता, और यह ऑडिट, Sectigo के cross-signing और सत्रह महीनों तक production-adjacent infrastructure में चलती रही, इससे पहले कि किसी ने सबसे स्पष्ट तरीका आज़माया: एक बाइट को brute-force करना। PKI के बारे में पाँच ऐसी मान्यताएँ हैं जिन्हें यह घटना पूरी तरह ध्वस्त कर देती है।
मिथक 1: “जो certificate संरचना के हिसाब से वैध है, वह सुरक्षित भी है”
पाइपलाइन की हर स्वचालित जाँच ने कहा कि ये certificates ठीक हैं। और संकीर्ण, बेकार अर्थ में वे सही भी थे। d = 4 से मेल खाने वाली public key P-384 curve पर एक पूरी तरह वैध point है। ASN.1 encoding पार्स हो जाती है। signature verify हो जाता है। chain बन जाती है। हर linting tool, हर structural validator, हर compliance checklist जो certificate को जाँचकर बताती है कि वह well-formed है, इन्हें पास कर देगी, क्योंकि ये सच में well-formed हैं।
यही जाल है। Structural validation इस सवाल का जवाब देता है कि “क्या यह सही फ़ॉर्मेट का certificate है?” यह इस सवाल का जवाब नहीं देता कि “अंदर की कुंजी सही तरीके से generate हुई थी?” elliptic curve keys के लिए ये दोनों गुण लगभग पूरी तरह स्वतंत्र हैं। प्राइवेट कुंजी बस एक scalar d है; public key d × G है, जहाँ G curve का generator point है। पूरा सुरक्षा तर्क इसी पर टिका है कि public point से d निकालने के लिए discrete logarithm problem हल करनी पड़ती है — लेकिन तभी, जब d वास्तव में पूरे 384-bit space से चुना गया हो। अगर d को 8 बिट्स से चुन लिया जाए, तो “असंभव” समस्या ऐसा लूप बन जाती है जो ज़्यादा से ज़्यादा 255 iterations चलता है।
इससे बने certificate में इसका कोई संकेत नहीं मिलता। d = 4 से निकला public point उतना ही random दिखता है जितना सही तरीके से generate की गई कुंजी से निकला हुआ। आप इसे देखकर नहीं पहचान सकते। आप इसे lint भी नहीं कर सकते। इसे जानने का एकमात्र तरीका छोटे मानों और ज्ञात कमज़ोर patterns को आज़माना है — और ठीक यही हुआ: रिपोर्टर ने Google का paranoid_crypto test suite, Common CA Database corpus के खिलाफ, जैसे का तैसा चलाया, और हिट मिला। एक ऐसी जाँच जो लैपटॉप पर मिलीसेकंड में हो जाती है, और जो उन कुंजियों पर चलती है जो असली browsers में भरोसे की जड़ हैं।
तो पहला सबक: वैधता ज़रूरी है, पर पर्याप्त कहीं से नहीं। अगर आपकी PKI टेस्टिंग “certificate parse होता है और chain बनती है” पर रुक जाती है, तो आप लिफ़ाफ़े को टेस्ट कर रहे हैं और मज़मून को नज़रअंदाज़ कर रहे हैं।
मिथक 2: “Baseline requirements और ऑडिट key-generation की गलतियाँ पकड़ लेते हैं”
CA, CA/Browser Forum Baseline Requirements के तहत चलते हैं और WebTrust या ETSI criteria पर ऑडिट होते हैं। वहाँ ceremony documentation, HSM requirements, key length requirements सब होते हैं। eMudhra की कुंजियों की लंबाई सही थी — कागज़ पर 384 bits। ऑडिट की खामी यह है कि compliance key के representation की जाँच करता है, उस process entropy की नहीं जिसने उसे बनाया। 47 ज़ीरो बाइट्स से भरी कुंजी फिर भी डिस्क पर 48 बाइट्स घेरती है।
eMudhra के अपने बयान के अनुसार, जो Mozilla के incident ticket पर पोस्ट हुआ, root cause किसी dark comedy जैसा है: ceremony script के एक bug ने HSM पर एक दूसरी, कमज़ोर key pair बना दी; दोनों pairs के नाम मिलते-जुलते थे; एक इंसान ने CSR के लिए गलत pair चुन लिया। तीन अलग-अलग विफलताएँ — script का bug, नामों का टकराव, और चयन की गलती — और किसी भी control ने एक बार भी यह नहीं पूछा कि “क्या इस कुंजी में वह entropy है जिसके लिए हमने HSM का पैसा दिया था?”
यह हिस्सा हर उस engineer को चिंतित करना चाहिए जो अपनी internal PKI चलाता है। अगर एक सार्वजनिक रूप से भरोसेमंद CA, जिसके पीछे root programs लगे हैं और जिसकी ऑडिट कैलेंडर पर है, 4 के बराबर प्राइवेट कुंजी भेज सकता है, तो आपके Vault PKI backend या Active Directory Certificate Services templates के अंदर क्या है? इसका समाधान सस्ता है और इसे न चलाने का कोई बहाना नहीं। कोई भी कुंजी generate करने के बाद, और उससे कुछ भी sign करने से पहले, उसे paranoid_crypto से या कम से कम एक सरल sanity check से गुज़ारें:
from cryptography.hazmat.primitives.asymmetric import ec
CURVE_ORDER_BITS = 384
def sanity_check_private_key(key: ec.EllipticCurvePrivateKey) -> None:
d = key.private_numbers().private_value
# Reject keys whose effective entropy is far below the curve size.
# A healthy P-384 key should have a bit length close to 384.
if d.bit_length() < CURVE_ORDER_BITS - 32:
raise ValueError(
f"Suspiciously small private scalar: {d.bit_length()} bits"
)
# Also reject known bad values outright.
if d < 2**16:
raise ValueError("Private scalar is trivially brute-forceable")
बस तीस सेकंड का काम। eMudhra की आठों कुंजियों में से हर एक को यह पकड़ लेता। ऑडिट यह verify करते हैं कि प्रक्रियाएँ मौजूद हैं; वे यह verify नहीं करते कि अप्रैल के किसी भी मंगलवार को प्रक्रिया ठीक चली थी। यह काम केवल output testing करती है।
मिथक 3: “समझौता हुई CA key को सीमित किया जा सकता है”
जब किसी CA key को आम अर्थ में “compromise” कहा जाता है, तो एक चोर होता है। किसी ने किसी खास पल में कुंजी चुराई, और आप blast radius का अनुमान लगा सकते हैं: चोरी के बाद चुराई हुई कुंजी वाले पक्षों द्वारा जारी certs। भयानक है, पर सीमित। हमने पहले लिखा है कि जब कोई intermediate CA compromise trust chain को तोड़ देता है, तब क्या होता है, और मानक playbook — revoke, distrust, reissue — एक “पहले” और “बाद” मानता है।
इस घटना में कोई “पहले” और “बाद” नहीं है। certificate बनने के क्षण से ही कुंजी व्यावहारिक रूप से सार्वजनिक थी, क्योंकि जो भी certificate को देखता, वह उसे मिलीसेकंड में निकाल सकता था। सीमित करने के लिए कोई चोरी की घटना नहीं है। खिड़की उन certificates के पूरे जीवनकाल की है — अप्रैल 2025 से आगे — और यह जानने का कोई तरीका नहीं कि खुले दरवाज़े से कौन, अगर कोई गुज़रा। eMudhra का यह बयान कि intermediates ने कोई end-entity certificate जारी नहीं किया, जिसकी पुष्टि Certificate Transparency logs से होती है, उन CAs के किए कामों के लिए सच में आश्वस्त करता है। पर यह नहीं बताता कि d=4 रखने वाला कोई भी व्यक्ति नेटवर्क पथ पर मौका मिलने पर क्या कर सकता था।
इससे भी बुरा यह है कि प्रतिक्रिया पूरी तरह लागू नहीं हो सकती। Chrome और Firefox ने घंटों के भीतर CRLSet और OneCRL के ज़रिए intermediates को block कर दिया, और दोनों को CT logging चाहिए, इसलिए जाली TLS certs उन browsers में वैसे भी validate नहीं होते। अच्छा है। पर यह सुरक्षा browser की सीमा पर खत्म हो जाती है, और यही हमें अगले मिथक तक ले जाता है।
मिथक 4: “अगर browsers सुरक्षित हैं, तो पूरा ecosystem सुरक्षित है”

Browsers TLS ecosystem का सबसे अच्छा परिदृश्य हैं, और वे उन TLS clients में से अल्पसंख्यक हैं जो परिचालन के लिए आपके काम के हैं। सोचिए कि आपके infrastructure में HTTPS connections असल में क्या बनाता है: curl, Python के requests, Node, Go binaries, Java services, git, package managers, cloud SDKs। इन clients में तीन गुण होते हैं जो यहाँ बुरी तरह मिल जाते हैं: ये disk पर रखे CA bundle पर भरोसा करते हैं, डिफ़ॉल्ट रूप से revocation नहीं जाँचते, और Certificate Transparency नहीं जाँचते। Chrome उपयोगकर्ताओं को बचाने वाली तीनों सुरक्षाएँ यहाँ गायब हैं।
Scott Helme ने इसे ठोस रूप से दिखाया: api.stripe.com के लिए एक जाली certificate, जो कमज़ोर eMudhra intermediates में से एक से chain होता है, डिफ़ॉल्ट curl ने SSL certificate verify ok बताया, Python ने handshake पूरा कर लिया, Node ने connection को authorized बताया, और Windows CryptoAPI ने chain स्वीकार कर ली। हर परीक्षण किए गए Linux और macOS मशीन पर। किसी भी hostname के लिए जाली cert, उन डिफ़ॉल्ट tools द्वारा स्वीकृत जिन पर आपकी deployment scripts और CI runners बने हैं। यह browser की समस्या नहीं; यह आपके infrastructure की समस्या है।
खतरे का नक्शा ज़्यादातर लोगों की कल्पना से बदतर है:
- curl | sh installers और self-updaters। rustup, nvm, Homebrew installer, और अनगिनत “install.sh” पेज। यहाँ जाली cert का मतलब अक्सर root के रूप में attacker का code चलाना है।
- CI/CD pipelines। Runners dependencies लाते हैं और artifacts push करते हैं, साथ में cloud credentials और signing keys रखते हुए, अक्सर पुराने base images पर।
- Server-to-server traffic। Payment webhooks, OAuth token exchanges, headers में secrets लेकर चलने वाली cloud SDK calls।
- IoT और embedded devices। जमी हुई firmware, जिसके CA bundles तब तक नहीं बदलेंगे जब तक certificates expire न हो जाएँ — जुलाई 2039 में।
- Windows code signing। आठ कमज़ोर कुंजियों में से दो code-signing CAs की थीं; उनसे sign किया गया malware किसी वैध publisher के software जैसा दिखता है।
व्यावहारिक सलाह उबाऊ और सही है: हर उस चीज़ को update करें जो CA bundle भेजती है। आपका OS ca-certificates package, certifi, Node, Homebrew — और जब base images distrust को अपना लें, तब अपने container images दोबारा build करें, क्योंकि layers याद रखती हैं। जो बात व्यावहारिक नहीं है, वह है वह device जिसे आप update नहीं कर सकते। वह smart TV अगले डेढ़ दशक तक 4 के बराबर कुंजी पर भरोसा करता रहेगा। अगर IoT gear को network segment करने के लिए एक और तर्क चाहिए था, तो यही है।
मिथक 5: “कोई न कोई इसे ज़रूर जाँच रहा होगा”
घटना की सबसे चुपचाप चुभने वाली पंक्ति रिपोर्टर की ओर से आई: खोज तब हुई जब रिपोर्टर ने subscriber certificates पर जाने से पहले CCADB corpus पर paranoid_crypto को एक त्वरित corpus test के रूप में चलाया। सबसे आसान फल। रिपोर्टर के अपने शब्द: “मेरा ज़्यादातर समय उन बुनियादी बातों को दोबारा जाँचने में गया जिन्हें हर किसी ने मान लिया था कि कोई और पहले ही कर चुका है — सुरक्षा के आसपास यह एक गंभीर गलती है।”
ज़रा फिर से पढ़िए। आठ CA private keys — एक सार्वजनिक रूप से भरोसेमंद authority के सबसे कीमती हिस्से, जो Sectigo के AAA Certificate Services root से cross-signed थे — सत्रह महीनों तक brute-force किए जा सकने योग्य पड़ी रहीं, और उन्हें न किसी auditor ने पकड़ा, न किसी root program ने, न CA ने खुद, बल्कि एक व्यक्ति ने, एक open-source tool को जैसे का तैसा चलाकर। इकोसिस्टम ने सामूहिक रूप से मान लिया था कि बुनियादी बातें कवर हैं। बुनियादी बातों को किसी ने कवर नहीं किया था।
यह security infrastructure में एक व्यापक पैटर्न है, और इसीलिए मैं defensive engineering — ऐसे systems जो आपदा का प्रतिरोध करते हैं, उन systems के बजाय जो सही संचालन मान लेते हैं, इस पर बार-बार ज़ोर देता रहता हूँ। इस गलती को पकड़ने वाली जाँचें लगभग शर्मनाक रूप से सस्ती हैं:
- हर कुंजी के generate होने के समय, और हर CSR को sign करने से पहले,
paranoid_cryptoया बराबर की weak-key जाँच चलाएँ। - Entropy को अनुभवजन्य रूप से verify करें: private scalar की bit length जाँचें और जिसकी प्रभावी entropy अविश्वसनीय रूप से कम हो, उसे अस्वीकार करें, जैसा ऊपर के code sample में है।
- Config ही नहीं, ceremony की भी जाँच करें। अपनी key ceremonies का dry-run करें और उत्पादित artifacts की असली जाँच करें, जिसमें यह भी शामिल है कि CSR में कौन सा नामित HSM object जाता है।
- सिर्फ़ templates नहीं, जारी किए गए certificates को भी लगातार scan करें। certificate ही ground truth है; उससे पहले की हर चीज़ केवल इरादा है।
Certificate ही ground truth है। उससे पहले की हर चीज़ — scripts, ceremonies, ऑडिट — बस इरादा है।
आठ बिट्स ही काफ़ी हैं
एक बेतुके कारण वाली तबाही में कुछ लगभग सुकून देने वाला है। एक script का bug, HSM पर दो मिलते-जुलते नामों वाली कुंजियाँ, और एक इंसान का गलत को चुन लेना — कोई राष्ट्र-राज्य नहीं, कोई नई cryptanalysis नहीं, बस सत्रह महीनों की फ़्यूज़ वाला एक हास्यास्पद किस्सा। पर यही बेतुकापन चेतावनी है। अगर किसी सार्वजनिक रूप से भरोसेमंद CA की सबसे कमज़ोर कड़ी एक बाइट हो सकती है, तो आपकी PKI की मज़बूती आपके curve चुनाव या HSM के बजट से तय नहीं होती। वह इस बात से तय होती है कि पाइपलाइन में कहीं भी किसी ने वास्तव में output की जाँच की या नहीं।
Browser vendors ने घंटों में अपना हिस्सा कर दिया। बाकी हमारे ज़िम्मे है: अपनी key generation का ऑडिट करें, सस्ती जाँचें चलाएँ, हर पहुँच योग्य CA bundle को update करें, और जिन devices तक पहुँच नहीं, उन्हें segment करें। और यह मानना बंद करें कि बुनियादी बातें किसी और ने पहले ही जाँच ली हैं। Security में, यही सबसे महँगी मान्यता है।


