
The Private Key Was Four
Every time a browser loads a page over HTTPS, it is trusting a chain of signatures. A certificate authority signs the website’s certificate, and the browser accepts it because that authority sits on a short list the bro…
以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。
Every time a browser loads a page over HTTPS, it is trusting a chain of signatures. A certificate authority signs the website’s certificate, and the browser accepts it because that authority sits on a short list the browser ships with. Publicly trusted CAs keep their top-level root keys offline and do their daily signing with intermediates, subordinate keys the root has vouched for. Whoever holds an intermediate’s private key can issue a certificate for any website, and browsers will accept it.
So everything rests on the private key staying secret and unguessable. For the elliptic curve in this story, P-384, a private key is a number picked at random from a range about 116 digits long. No computer that will ever be built could search that range.
In April 2025 eMudhra, a certificate authority based in India and trusted by Apple, Google, Microsoft and Mozilla, created a batch of new intermediates. The private key of one of them, EM OV TLS CA - G3C, was the number 4. Written out as a P-384 key it looks like this:
00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000004
A properly generated one looks like this:
84ac06790886c80c48d31691fd4c0fe9 ce3207f9807f2fe571d6e4ec426d7864 4298fc53df2b92566970e757ac998c34
The keys came out of a key ceremony, the scripted and witnessed session in which a CA generates keys inside its hardware security modules. Seven sibling intermediates from the same ceremony were no better. Their private keys were 56, 66, 115, 155, 156, 230 and 237. Every one was below 256. Anyone with a copy of the certificate could recover the key by trying each number from 1 to 255 until one produced the public key printed in the certificate. I checked all eight myself. It takes less time than reading this sentence.
Those certificates were public the whole time. CAs must disclose every intermediate in the CCADB, the shared database the browser root programs use to track CAs, and these went in on 10 May 2025. On 17 October 2026 a researcher who goes by Wayne ran paranoid_crypto, a free key-testing tool Google released in 2022, over the CA certificates in CCADB. Twenty-seven minutes after he started, it flagged the eight keys. About two hours later he reported them to Apple, Chrome, Microsoft, Mozilla and eMudhra, with a message signed by each key as proof. Chrome blocked the six intermediates that could issue website certificates within two hours of his email, and Mozilla within five. By 20 October both had decided to remove the eMudhra root above them, emSign ECC Root CA - G3, entirely. On 22 October eMudhra announced it was leaving the global TLS certificate business.
The proof was barely needed. Dennis Jackson of Mozilla recovered all eight keys independently within two hours of receiving the report, and noted that AI agents running on his own machine recovered them on the first try when told the task was a capture-the-flag puzzle. Within three days several people had posted the keys, and one showed a forged google.com certificate working against an unpatched client.
For seventeen months, then, the private keys of six website-signing intermediates trusted by every major browser could be computed by anyone who looked. Wayne had even seen the first symptom. In June 2025 he commented on one of two public bug reports that, as it turns out, documented these exact keys misbehaving. eMudhra had the same evidence in hand that June. It knew its certificates did not hold the keys it meant them to hold, switched to the keys the certificates named, and kept operating for sixteen more months.
The 30 April 2025 ceremony produced 24 issuing CAs in three series (A, B and C), each with RSA-4096 and P-384 versions for DV, OV, EV and code signing. The HSM mapping eMudhra posted shows the A series was generated on an Entrust nShield Connect XC, and the B and C series on a Utimaco Se-Series Gen2. Only the P-384 keys from the Utimaco went wrong. The RSA siblings from the same Utimaco look sound on every cheap test I ran (no shared factors with any other CCADB key, no Fermat weakness, no small factors), though cheap tests prove nothing about generation. The B series belonged to eMudhra BV in the Netherlands and the C series to eMudhra Inc in the US. eMudhra says they were built for data-sovereignty customers and only one, EM DV TLS CA - G3C, was ever switched on. None issued a certificate.
On 29 May 2025 eMudhra published CRLs for six of the new intermediates, the same six TLS CAs whose keys were later recovered. None of the signatures verified. crt.sh flagged them, and on 3 June Rob Stradling of Sectigo sent eMudhra a problem report asking whether the CRLs had been signed with the wrong private key. The email sat in a spam quarantine. On 5 June he opened Bug 1970728.
eMudhra’s incident report said a manual CRL process had used an incorrect CA key configuration. The keys came from the issuing environment but did not match the keys expected for those CRLs. It regenerated the CRLs, and committed to automating CRL signing and verifying every CRL after signing. The bug closed on 16 July 2025.
The CRLs eMudhra attached to that bug say more than the report does. From an ECDSA signature and the signed data you can compute the small set of candidate public keys that could have made it, usually two. eMudhra attached five distinct CRLs, uploading one of them twice and leaving out EM DV TLS CA - G3B. I did that for each. Every candidate verifies the signature, none has a small private value, none matches the key in the CA’s certificate, and no candidate key appears in any of the 10,313 CA certificates in CCADB. So in June 2025 these CAs each had two keys on the HSM. One was a normal key that eMudhra’s systems treated as the CA’s key. The other was the key the certificate actually certified.
In October 2026 eMudhra explained what happened next. The CRLs had been signed with the original keys, the ones generated with appropriate entropy. Those signatures failed, so eMudhra re-signed them with the flawed keys. The fix for the invalid CRLs was to start using the weak keys, because they were the ones that matched the certificates.
That was the decision that mattered. eMudhra held cryptographic proof that its certificates did not contain the keys its systems treated as the CA’s, and it resolved the discrepancy in favor of the certificates. Then it kept those CAs in service for another sixteen months. The 2025 investigation reached the right symptom and stopped one question short. Both of its action items concerned the CRL signing path. Neither asked why a CA had two keys, which one was legitimate, or whether the certified key had been generated as intended. Answering that required no cryptanalysis, only treating “the expected key does not match the certificate” as a question about the certificate rather than about the CRL tooling.
According to eMudhra’s preliminary root cause, the 30 April ceremony included an approved deviation to test key wrap and unwrap, because the B and C series keys were meant for export to European and US data centers. A flaw in the script generated a second, weak key pair on the Utimaco HSM. The key labels were similar, and the CSRs were built from the weak keys.
Each CA held two keys, and the fix put the weak one to workOne of the six TLS CAs, from eMudhra's account and the keys recovered from its CRLs30 Apr 2025 key ceremony on the Utimaco HSMStrong keyGenerated as intendedMatches no certificateWeak keyLeft by the wrap and unwrap testPrivate value below 256Treated as the CA keyby eMudhra's CRL signingCSR built from the weak keySimilar key labels on the HSM29 May 2025 CRLsSigned with the strong keyNo signature verifiesCA certificateCertifies the weak keyCCADB 10 May, Sectigo 14 May6 Jun 2025 fixCRLs re-signed with the weak key, so they verifysignatures failkey matches the certificate
eMudhra has not published the script, the mechanism and parameters it passed to C_WrapKey, or the attribute template it gave C_UnwrapKey. A wrong parameter, or a mismatch between the encoding the wrap produced and the one the unwrap expected, could turn a 384-bit scalar into a single byte. Every recovered key is below 256, which fits a parsing error far better than a weak random number generator. The ceremony needed a known-answer test before any production key went through that path. Wrap a key generated in software under a wrapping key the operator also holds in software, decrypt the blob to confirm its encoding, unwrap it on the HSM, and check that the resulting public key matches the original. That dry run belongs after every change to the script or the HSM firmware as well.
Commenters in the bug have pressed the same point. eMudhra’s own CP says issuing CA keys are generated in a device that is at least FIPS 140-2 Level 3. A P-384 scalar below 256 is not something approved in-module generation produces, so the weak keys most likely came from material the script supplied, through a call such as C_UnwrapKey or C_CreateObject. In that case the weak keys may never have been confined to an HSM at all. The private value existed outside the module wherever the script ran, and possibly in its logs, before it was loaded. With a key below 256 the secrecy question is moot, since anyone can compute it. The control question is not. A CA key that was loaded rather than generated inside the module does not meet eMudhra’s own CP. One commenter has asked eMudhra for the script, the exact call, whether the module was in its FIPS-approved mode, and who approved the deviation. Another proposed that root programs require a manufacturer-signed attestation that every CA key was generated inside the HSM rather than loaded into it. eMudhra’s public statement says it has not yet confirmed the exact root cause.
The 2025 report even has a section titled “Where we got lucky”. It says the new intermediates had not yet issued any end-entity certificates, which limited the exposure. That was true, and for a reason the authors could not see. Its lessons-learned section called for automating manual steps in creating new issuing CAs. Automating CRL signing against the certified key would only have put the weak keys to work sooner.
The auditors saw this incident too. BDO’s WebTrust report for June 2025 through May 2026 lists all eight affected intermediates in scope, names Bug 1970728 as an Other Matter, and says the auditor examined the disclosed root cause. The opinion was unmodified. The ceremony itself fell in the prior audit period, and I have not been able to find that report.
Once eMudhra chose the certificates over its own key records, nothing else in the system was positioned to catch it. Six publicly trusted keys sat in plain view for seventeen months because no rule asked anyone except eMudhra to look, and the one check the rules recommend would have passed them.
The ECDSA quality check in section 6.1.6 is NIST public-key validation, and it is a SHOULD. It confirms the point is on the curve and has the right order. A private key of 4 produces a perfectly valid point. Public-key validation looks only at the point, so by design it cannot tell how the private key was chosen. The recommended check would have passed every one of these keys.
The check that did work has existed for years. Google published paranoid_crypto in June 2022. Its CheckWeakECPrivateKey test, a default check rated critical, looks for EC keys whose private value fits in 32 bits. It was public nearly three years before these keys were generated.
I wanted to know what running it at disclosure time would cost, so I pulled every CA certificate in CCADB, 10,313 of them, and tested each EC key for a private scalar below 65,536. The scan took 0.3 seconds after a one-time table build of under a minute. It returned exactly sixteen certificates. Eight were the eMudhra intermediates and eight were Sectigo’s cross-certificates of the same keys. There were no false positives. A batch GCD across all 6,
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。