Neil Madden
neilmadden.blog · Personal blog · on HN since 2019
Neil Madden, a security engineer, writes about cryptography, OAuth, Java security, and post-quantum cryptography.
What HN saysHN commenters cite his review of Cloudflare's AI-coded OAuth library and his post on key-driven cryptographic agility.
56HN people shared it
26linked it in comments
43stories submitted
1.9Kstory points
4 months agolast shared
2019people per year2026
Most-shared posts
- 1A few comments on ‘age’7 people · 82 points · first shared 2019 · 18 comments on HN
- 2Psychic Signatures in Java5 people · 309 points · first shared 2022 · 116 comments on HN
- 3A look at Cloudflare's AI-coded OAuth library5 people · 271 points · first shared 2025 · 165 comments on HN
- 4Rating 26 years of Java changes5 people · 256 points · first shared 2025 · 321 comments on HN
- 5What’s the Curve25519 clamping all about?4 people · 5 points · first shared 2020 · discussion on HN
- 6Galois/Counter Mode and random nonces3 people · 66 points · first shared 2024 · 26 comments on HN
- 7Why the OAuth mTLS spec is more interesting than you might think3 people · 10 points · first shared 2022 · discussion on HN
- 8Are we overthinking post-quantum cryptography?3 people · 5 points · first shared 2025 · 2 comments on HN
- 9Hybrid encryption and the KEM/DEM paradigm3 people · 1 points · first shared 2023 · discussion on HN
- 10On PBKDF2 Iterations3 people · 1 points · first shared 2023 · discussion on HN
- 11Digital signatures and how to avoid them2 people · 282 points · first shared 2024 · 82 comments on HN
- 12Moving Away from UUIDs (2018)2 people · 281 points · first shared 2020 · 230 comments on HN
- 13Is Datalog a good language for authorization?2 people · 68 points · first shared 2022 · 21 comments on HN
- 14Can you ever (safely) include credentials in a URL?2 people · 5 points · first shared 2021 · 4 comments on HN
- 15I don't use LLMs for programming2 people · 4 points · first shared 2026 · 1 comments on HN
What HN people wrote when they linked it
n4r9 · 2025-07-07
For a review of this library see https://neilmadden.blog/2025/06/06/a-look-at-cloudflares-ai-coded-oaut…
Upshot: though it's possible to attempt this with (heavily supervised) LLMs, it's not recommended.
nmadden · 2024-08-15
The best way to do cryptographic agility is to associate the algorithm with the key and negotiate keys (from a given set) only. Google’s Tink library does this very well. See https://neilmadden.blog/2018/09/30/key-driven-cryptographic-agility/ for some more background. Version numbers are just algorithm identifiers in another form.
throw0101a · 2025-08-11
> It costs:
Not wrong, but given these algorithms are mostly used at setup, how much cost is actually being occurred compared to the entire session? Certainly if your sessions are short-lived then the 'overhead' of PQC/hybrid is higher, but I'd be curious to know the actually byte and energy costs over and above non-PQC/hybrid, i.e., how many bytes/joules for a non-PQC exchange and how many more by adding PQC. E.g.
> Unfortunately, many of the proposed post-quantum cryptographic primitives have significant drawbacks compared to existing mechanisms, in particular producing outputs that are much larger. For signatures, a state of the art classical signature scheme is Ed25519, which produces 64-byte signatures and 32-byte public keys, while for widely-used RSA-2048 the values are around 256 bytes for both. Compare this to the lowest security strength ML-DSA post-quantum signature scheme, which has signatures of 2,420 bytes (i.e., over 2kB!) and public keys that are also over a kB in size (1,312 bytes). For encryption, the equivalent would be comparing X25519 as a KEM (32-byte public keys and ciphertexts) with ML-KEM-512 (800-byte PK, 768-byte ciphertext).
* https://neilmadden.blog/2025/06/20/are-we-overthinking-post-quantum-cr…
"The impact of data-heavy, post-quantum TLS 1.3 on the Time-To-Last-Byte of real-world connections" (PDF):
*…
nipah · 2025-06-12
Your estimation maybe right, but maybe also there is a point on why it is right: https://neilmadden.blog/2025/06/06/a-look-at-cloudflares-ai-coded-oaut…
Maybe because (and I'm quoting that article) it is still lacking in what it should have that you managed to accomplish this task in "few days" instead of "a few weeks, maybe months".
Maybe the bottleneck was not your typing speed, but the [specific knowledge] to build that system. Because if you know something well enough, you can build it way faster, like rebuilding something from scratch, you will be faster as you already know the paths. In which case, my question would be: would not be writing this as fast, or maybe at least more secure and reasonable, if you had the complete knowledge of the system first.
Because contrary to LLMs, humans can actually improve and learn when they do things, and they don't whey they don't do things. Not knowing the code to the full extent is worth the time "gained" by using the LLM to write it?
I think it's very hard to estimate those other aspects of the thing.
chlorion · 2022-06-11
I really like the general ideas behind age, like being composable in shell commands and having a more narrow focus than something like GPG.
My biggest frustration with GPG is that it needs to have keys imported to do anything useful. I greatly prefer just storing the keys in the file system!
Related to that last point, Gentoo uses GPG to verify distfiles sometimes and it ends up creating a lot of "dummy" keyrings and throwing them away to circumvent this limitation of GPG! (I haven't dug too deeply into the code so it's possible that I am wrong here, but this is my current understanding)
My two primary issues with age that have prevented me from using it are that it doesn't use authenticated encryption (see links below) and that there is no way to encrypt/decrypt and make signatures with a single key pair (at least afaik). If I am encrypting files I want to be able to trust the contents of it fully, otherwise it's really not that useful for me personally!
https://github.com/FiloSottile/age/issues/59
https://neilmadden.blog/2019/12/30/a-few-comments-on-age/
lucasluitjes · 2025-08-18
> I have recently written security-sensitive code using Opus 4. I of course reviewed every line and made lots of both manual and prompt-based revisions.
> Cloudflare apparently did something similar recently.
Sure, LLMs don't magically remove your ability to audit code. But the way they're currently being used, do they make the average dev more or less likely to introduce vulnerabilities?
By the way, a cursory look [0] revealed a number of security issues with that Cloudflare OAuth library. None directly exploitable, but not something you want in your most security-critical code either.
[0] https://neilmadden.blog/2025/06/06/a-look-at-cloudflares-ai-coded-oaut…
compressedgas · 2024-11-01
ramchip · 2024-08-11
See "Hybrid encryption and the KEM/DEM paradigm":
https://neilmadden.blog/2021/01/22/hybrid-encryption-and-the-kem-dem-p…
tl;dr: resistance to padding attacks, better support for non-RSA cryptosystems
zimmerfrei · 2024-06-30
I like it, because it is indeed nice to have a NIST-backed construction.
But at the same time, it is disappointing that you get locked out of several niceties of NIST KDFs, such as label and context. I get that they are sacrificed to minimize the number of AES calls, but still I would prioritize strong cryptographic separation over just a few saved AES calls, especially for messages longer than a few hundred bytes.
Finally, *random* GCM nonces longer than 96 bits are definitely misunderstood and bring better guarantees than 96 bits nonces [1]. But of course, if you can derive a fresh key for every message, that's definitely to prefer.
[1] https://neilmadden.blog/2024/05/23/galois-counter-mode-and-random-nonc…
frereit · 2024-06-12
> But it strangely leaves open the possibility, without saying either way, that a longer iv, with r(i)>96 random bits might allow generating more iv's. As you point out, it will depend on the properties of GHASH (and potentially on how the result is used downstream from there).
There is some details on the "GHASH as initial counter value" which seem to suggest that for larger nonces, the total number of messages shouldn't exceed 2^44.5 here: https://neilmadden.blog/2024/05/23/galois-counter-mode-and-random-nonc…
withinboredom · 2024-04-22
I’ve never seen the behavior you are describing. I would check that you’re sending the headers correctly: https://neilmadden.blog/2020/05/18/a-flowchart-for-cache-control-heade…
I’ve used that flowchart too many times.
refset · 2023-06-30
Likely of interest: https://neilmadden.blog/2022/02/19/is-datalog-a-good-language-for-auth… (Feb 2022 discussion: https://news.ycombinator.com/item?id=30400886)
franky47 · 2023-03-05
Another footgun is that Curve25519 has a cofactor of 8, which may reveal some information about your private key if some high-order points are used [1].
Some curves (eg: Ristretto) were designed to alleviate this problem.
[1] https://neilmadden.blog/2020/05/28/whats-the-curve25519-clamping-all-a…
jxcl · 2023-01-12
There was an article on HN earlier this week about PBKDF2 iterations[1]. The gist of the article was that adding iterations to the key derivation function doesn't actually increase the entropy of a password all that much. No matter how much education and encouragement they're given, some users will choose weak passwords, and those passwords will be crackable even with any reasonable number of DF iterations.
This was good support for 1PW's 2-key solution, since one of the keys is randomly generated with a true 128 bits of entropy, no matter what password the user chooses, a compromise of the service's data store alone will mean the user's vault encryption key is uncrackable.
[1]: https://neilmadden.blog/2023/01/09/on-pbkdf2-iterations/
Disclaimer: I'm an employee of 1Password.
rwbhn · 2022-04-20
This referenced article is better: https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/
Sniffnoy · 2022-04-20
Should this link instead to the article the tweet links to? https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/
duskwuff · 2022-04-01
Clear the highest bit, set the next highest bit, and clear the three lowest bits. This process is known as "key clamping", and ensures that the private key is in the right range and is not vulnerable to a couple of specific attacks.
https://neilmadden.blog/2020/05/28/whats-the-curve25519-clamping-all-a…
fXmBeWm3TQ · 2021-09-06
calling this format "secure" is not sufficient, here is a review that asked the right questions.
https://neilmadden.blog/2019/12/30/a-few-comments-on-age/
Unfortunately, the age spec doesn’t document its threat model or the security goals it is intended to achieve so I’m having to read between the lines to work out what was intended.
creamytaco · 2021-06-08
Signal and veracrypt are not PGP replacements, not even remotely close.
Regarding age, one reason is that it only supports a small fraction of PGP functionality thus useless for many real world applications. Another is that it operates on top of a fundamentally different model and for many folks that model is worse and potentially less secure than PGP's if you try to replicate PGP functionality by composition [1].
Modern doesn't necessarily equal good. PGP is mature and solid which is why it's still widely used and remains popular.
[1] https://neilmadden.blog/2019/12/30/a-few-comments-on-age/
bscphil · 2019-12-31
IMO the criticisms here make more sense if you also read the author's article series "Public key authenticated encryption and why you want it".
https://neilmadden.blog/2018/11/14/public-key-authenticated-encryption…
shadytrees · 2019-12-31
unscaled · 2026-05-23
> It's not "JWT is broken". The cryptography is fine. The tymondesigns/jwt-auth package is fine. The concept of using JWT as your app's session is what's broken.
If only that was true. JWT came with a lot of questionable cryptographic choices. It went hard on fine-grained cryptographic agility like it was 1995 all over again. It started with the wrong suite of outdated ciphers like RSA and no good security requirements and implementation guides, and even the notorious "none" algorithm. The end result is a string of CVEs that affected a wide swath of JWT libraries.
JWT has many other ill-conceived features such as embedded JWK, token-declared URLs and the complex mess that is JWE (which you'll need if you want encryption). This complexity, useless features (the "none" algorithm), together with picking algorithms that are hard to implement correctly[1] and not setting any kind of security requirements made vulnerable libraries spread like wildfire, and introduced at least 5 different classes of vulnerabilities[2].
The craziest thing, is that easiest vulnerability to abuse (the "none" algorithm), is a required by the JWT RFC, you read it too literally:
Of the signature and MAC algorithms specified in JSON Web Algorithms
JWA], only HMAC SHA-256 ("HS256") and "none" MUST be implemented by
conforming JWT implementations.
Now, the RFC writers obviously meant that conforming JWT libraries, should support "none" if explicitly requested, but did not mean that the libraries…
ho_schi · 2025-07-22
First:
Valid point about the image size. A possible sign for bloat? Bloat is danger.
Second:
C, C++ or Rust are our tools. Everyone prefers another for technical and personal reasons. A religious believe in salvation by the next programming language is not helpful and causing harm. I hope sanitizers for C/C++ improve further - which improved safety a lot. For C++28 or C++3x we can hope for further safety improvements. Which we need.
Most bugs are logic errors. SharePoint is - according to my knowledge - implemented in C#. The CVEs mention deserialization of untrusted data, improper limitation of a pathname to a restricted directory ('path traversal'), improper control of generation of code ('code injection') and so on.
I'm rather careful about people requiring another language and claiming it will fix everything. Reliability needs hard work (design, code, review, testing...more review) even with well selected tools. I guess Microsoft does that. And I guess Microsoft works like the rest of the industry, focus on time-to-market and building a monopoly in every area. That's why we see rapid updates in a lot areas and - worse - enforced updates. And why software is known for it's low quality in comparsion to other industries?
Examples:
GNOME opted to use JavaScript in the hype back in 2010:
* JavaScript reduced compatibility compared to C/C++. * They suffered a lot from memory-leaks. Due to JavaScript. * The run-time modification seems not to be a big…
vogr · 2024-09-20
I'm no cryptographer, but I would say that it is indeed the case that you can assume that two parties can derive a shared key over an untrusted channel. The post Cryptography Right Answers PQ [1], linked in another comment, addresses this in the section "Key Exchange". Rather than thinking about Diffie-Hellman directly, you would turn to a Key Exchange Mechanism (KEM).
Before post-quantum cryptography concerns, KEM were indeed mostly built on top of Diffie-Hellman key agreement, but you could also build one on top of RSA, or on top of some lattice constructs. But you wouldn't build one yourself, there are good constructions to choose from! The OP actually has a 3-part series on KEMs, although I don't think it addresses post-quantum issues [2].
[1]: https://www.latacora.com/blog/2024/07/29/crypto-right-answers-pq/ [2]: https://neilmadden.blog/2021/01/22/hybrid-encryption-and-the-kem-dem-p…
jchw · 2023-01-24
While the practice of not updating PBKDF2 iterations is bad, I think with LastPass the problem was more the aggregate of many things, a sort-of death by a million cuts. Because truthfully, the PBKDF2 iterations count issue was relatively unimportant. Some good conjecture about it:
https://neilmadden.blog/2023/01/09/on-pbkdf2-iterations/
Both Bitwarden and LastPass should improve this situation by making the iteration count automatically increase over time. For LastPass though, there are... A lot of concerns. The breach, how it was handled, persistent issues with the security of their browser extension (many, including an RCE at one point) and of course the fact that not everything in the vault is actually encrypted.
KeePass XC or 1password may prove to be better options from a strict security practices standpoint, but from what I've seen I don't suspect Bitwarden has a pattern of bad security practices overall. It does seem like there are opportunities to make it better, though.