<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/the-case-of-the-9-bit-aes-key-7rbggurdy" -->

---
title: The case of the 9 bit AES key | daily.dev
description: Several PDF applications that advertise AES-256 encryption actually derive their file keys from tiny or predictable random state. MuPDF versions before 1.28.5...
canonical: https://daily.dev/posts/the-case-of-the-9-bit-aes-key-7rbggurdy
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: The case of the 9 bit AES key | daily.dev
og:description: Several PDF applications that advertise AES-256 encryption actually derive their file keys from tiny or predictable random state. MuPDF versions before 1.28.5...
og:url: https://daily.dev/posts/the-case-of-the-9-bit-aes-key-7rbggurdy
og:image: https://api.daily.dev/og/posts/7RBGgUrdy.png
og:image:alt: The case of the 9 bit AES key
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# The case of the 9 bit AES key

**[Hacker News](https://daily.dev/sources/hn)** · 6 min read · 1 upvotes · 0 comments

## Summary

Several PDF applications that advertise AES-256 encryption actually derive their file keys from tiny or predictable random state. MuPDF versions before 1.28.5 seed a 48-bit LCG once from the current epoch second, and only 9 bits of that state end up affecting the AES-256 key, letting all 512 possible keys be brute-forced in about 11 milliseconds. Foxit PDF Reader 2026.1.3.36551 hashes the timestamp with 32 zero-filled 'uninitialized' bytes, so a Rust cracker on a Ryzen 9 7950X can test every timestamp since the Unix epoch in 4.85 seconds. OpenPDF 3.0.5 and iText 9.7.1 seed an ARC4 stream from a millisecond timestamp and JVM free memory, which is weaker but still far short of 256-bit security. The issues were reported to vendors, and MuPDF has fixed its generator.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://v12.sh/blog/the-case-of-the-9bit-aes-key>

## Questions this post answers

### why is MuPDF's AES-256 encryption for PDFs not actually secure

MuPDF versions before 1.28.5 seed their random number generator, a 48-bit linear congruential generator, once using the current epoch in seconds, and only 9 bits of that timestamp actually affect the output bytes used for the key. This means there are only 512 possible 32-byte keys, which can all be brute-forced and trial-decrypted in about 11 milliseconds.

_Developers vetting PDF libraries for real security guarantees can track disclosures like this on daily.dev._

### how does Foxit PDF Reader generate its AES-256 encryption key

Foxit PDF Reader 2026.1.3.36551 derives the file key by hashing the current timestamp together with 32 bytes meant to be uninitialized memory, plus a constant, but those 32 bytes are actually zero-filled and add no entropy. A Rust implementation using Rayon on a Ryzen 9 7950X with 32 threads can test 370 to 376 million candidate timestamps per second, cracking a key from the Unix epoch to now in 4.85 seconds.

_Anyone evaluating document encryption tools can keep up with weaknesses like this via daily.dev._

### how do OpenPDF and iText generate randomness for PDF file keys

OpenPDF 3.0.5 and iText 9.7.1 both use an IVGenerator class built on an ARC4 stream seeded with a millisecond timestamp and the JVM's free memory at the time. This source has more variance than MuPDF or Foxit's approach, but it still falls well short of true 256-bit security since both seed values can be guessed and checked against plaintext salts stored in the PDF's /U and /O fields.

_Java developers relying on these libraries for encryption can follow fixes to this via daily.dev._

## Community take

How the wider developer community reacted, aggregated from 1 discussion and 56 comments across hackernews (as of 2026-10-29).

**TL;DR:** The discussion centers less on the specific PDF key flaws and more on a broader tangent about memory-unsafe languages (especially C) being unsuitable for parsing untrusted file formats, alongside disbelief that basic crypto mistakes like weak RNG seeding keep recurring.

**Sentiment:** 5% positive · 25% mixed · 70% skeptical

**The pushback**

- Using C (or other memory-unsafe languages) for parsing untrusted, complex formats like PDF is seen as inherently risky.
- Rolling your own RNG instead of using a cryptographically secure system RNG is called out as a basic, avoidable mistake.
- Several note that the real problem isn't just key bit-length but that the keys aren't cryptographically random at all.
- Some argue weak encryption is effectively equivalent to no encryption.

**By community**

- hackernews (heated): A long tangent debates whether C is appropriate for PDF parsing and what safer alternatives (Rust, WUFFS, PDF.js) exist, while others push back that language choice rarely matters to most users; a separate thread argues about engineering licensing and whether these are basic, avoidable mistakes.

**Hottest debate:** Whether memory-unsafe languages like C are fundamentally unsuitable for parsing untrusted file formats, and which safer alternative (Rust vs. WUFFS vs. rewriting in something else) is actually the right fix.

**Open questions**

- What is the appropriate rigorous testing methodology when AI-assisted coding is involved?
- Is the recurrence of weak RNG seeding across multiple PDF tools coincidental or indicative of a systemic industry problem?

**Highlights**

> "MuPDF versions before 1.28.5 use an implementation of the drand48 family" yeah, ok, so they're basically not doing real encryption. The number of bits in the key space isn't the real story; the keys simply aren't cryptographically random.
> — [tptacek on hackernews · 1 comments](https://news.ycombinator.com/item?id=50281944)

> File formats are the buffer issue honeypot. You may be aware of how often video and audio codecs have vulnerabilities - it's nearly never the hand-tuned frame decode assembly (where you would think all the mistakes would be). It's nearly always the thing that reads the metadata and encoded frames to memory. Binary formats have things like offsets in them, and those can be trivially used to overrun. Same thing applies here. Even Rust has a crate for dealing with binary data, despite its memory promises: https://crates.io/crates/untrusted It's a fucking minefield, and this is one area where the Rust zealots are undeniably correct. It doesn't have to be Rust, any memory safe language will do, but Rust also happens to be performance competitive and that's usually also desirable.
> — [zamalek on hackernews · 1 comments](https://news.ycombinator.com/item?id=50282347)

> What is wrong with software engineers that we keep making really stupid basic mistakes like this? Sometimes I think programming should require licensing and regular testing.
> — [NelsonMinar on hackernews · 4 comments](https://news.ycombinator.com/item?id=50282234)

> Does the DMCA still make it illegal to access encrypted content no matter how easy it is to discover the key? https://www.law.cornell.edu/uscode/text/17/1201 Would the new LLM model owners like to strike this down, or use it to demonstrate how dangerous unrestricted models can be?
> — [jburgess777 on hackernews · 1 comments](https://news.ycombinator.com/item?id=50282482)

> That's way too many PDF implementations affected by this category of stupidity. It makes me wonder: Coincidence, really? There's enough there to think that there might be some invisible hand behind it.
> — [snvzz on hackernews](https://news.ycombinator.com/item?id=50284435)

**Source threads**

- [hackernews](https://news.ycombinator.com/item?id=50280722) · 99 points · 56 comments

## Similar posts on daily.dev

- [Breaking More Encrypted USB Drives with AI](https://daily.dev/posts/breaking-more-encrypted-usb-drives-with-ai-uxau1dgim) · Binary Ninja · 0 upvotes · 0 comments
- [Contrary to popular superstition, AES 128 is just fine in a post-quantum world](https://daily.dev/posts/contrary-to-popular-superstition-aes-128-is-just-fine-in-a-post-quantum-world-lz9z1ekgh) · Ars Technica · 0 upvotes · 0 comments
- [Carelessness versus craftsmanship in cryptography](https://daily.dev/posts/carelessness-versus-craftsmanship-in-cryptography-rh1tygiet) · Hacker News · 0 upvotes · 0 comments

---

Tags: [#cryptography](https://daily.dev/tags/cryptography)

[View this post on daily.dev](https://daily.dev/posts/the-case-of-the-9-bit-aes-key-7rbggurdy)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"The case of the 9 bit AES key","url":"https://daily.dev/posts/the-case-of-the-9-bit-aes-key-7rbggurdy","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/the-case-of-the-9-bit-aes-key-7rbggurdy"},"datePublished":"2026-10-28T23:56:08.881Z","dateModified":"2026-10-29T05:15:29.264Z","description":"Several PDF applications that advertise AES-256 encryption actually derive their file keys from tiny or predictable random state. MuPDF versions before 1.28.5...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d53bbb50657f91d2f1c2903c330f7c39?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d53bbb50657f91d2f1c2903c330f7c39?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Hacker News","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Hacker News","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/hn","url":"https://daily.dev/sources/hn"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/the-case-of-the-9-bit-aes-key-7rbggurdy","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"cryptography","timeRequired":"PT6M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Hacker News","item":"https://daily.dev/sources/hn"},{"@type":"ListItem","position":3,"name":"The case of the 9 bit AES key"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/the-case-of-the-9-bit-aes-key-7rbggurdy#faq","mainEntity":[{"@type":"Question","name":"why is MuPDF's AES-256 encryption for PDFs not actually secure","acceptedAnswer":{"@type":"Answer","text":"MuPDF versions before 1.28.5 seed their random number generator, a 48-bit linear congruential generator, once using the current epoch in seconds, and only 9 bits of that timestamp actually affect the output bytes used for the key. This means there are only 512 possible 32-byte keys, which can all be brute-forced and trial-decrypted in about 11 milliseconds. Developers vetting PDF libraries for real security guarantees can track disclosures like this on daily.dev."}},{"@type":"Question","name":"how does Foxit PDF Reader generate its AES-256 encryption key","acceptedAnswer":{"@type":"Answer","text":"Foxit PDF Reader 2026.1.3.36551 derives the file key by hashing the current timestamp together with 32 bytes meant to be uninitialized memory, plus a constant, but those 32 bytes are actually zero-filled and add no entropy. A Rust implementation using Rayon on a Ryzen 9 7950X with 32 threads can test 370 to 376 million candidate timestamps per second, cracking a key from the Unix epoch to now in 4.85 seconds. Anyone evaluating document encryption tools can keep up with weaknesses like this via daily.dev."}},{"@type":"Question","name":"how do OpenPDF and iText generate randomness for PDF file keys","acceptedAnswer":{"@type":"Answer","text":"OpenPDF 3.0.5 and iText 9.7.1 both use an IVGenerator class built on an ARC4 stream seeded with a millisecond timestamp and the JVM's free memory at the time. This source has more variance than MuPDF or Foxit's approach, but it still falls well short of true 256-bit security since both seed values can be guessed and checked against plaintext salts stored in the PDF's /U and /O fields. Java developers relying on these libraries for encryption can follow fixes to this via daily.dev."}}]}
```

