HNHacker News
TopNewBestAskShowJobs

FiloSottile

10,859 karma · joined May 9, 2012

https://filippo.io

[ my public key: https://keybase.io/filippo; my proof: https://keybase.io/filippo/sigs/c51KtcfccPH0D3jG9PtQBZZh6AqhvB5MHIz2YmkupAc ]

submissionscomments
FiloSottile··on Go 1.21 Released
Go is absolutely committed to the cryptography standard library. What's happening is that we're deprecating legacy protocols and APIs to invest resources on packages that better align with the Cryptography Principles [0].

In particular, crypto/elliptic was an unfortunate API that has been deprecated in favor of the new crypto/ecdh. Most applications can migrate (on their own time, as we don't break backwards compatibility even for deprecated packages) and get better security and performance. (A very small portion of applications might need lower level applications, in which case they can use third party modules based on the stdlib internals, like filippo.io/nistec.) You can read more on my Go 1.20 [1] and Go 1.21 [2] posts.

[0]: https://golang.org/design/cryptography-principles [1]: https://words.filippo.io/dispatches/go-1-20-cryptography/ [2]: https://words.filippo.io/dispatches/go-1-21-plan/

FiloSottile··on BGP.Tools: Browse the Internet Ecosystem
Quoting for endorsement.

Ben, of https://blog.benjojo.co.uk [1] and https://age-encryption.org/design fame, built something genuinely useful out of sheer technical depth, use case understanding, and experience.

I don't really work with networks but the changelog is indeed a great read because 1) I learn stuff, and 2) it's great to see a useful focused product just get better.

[1] https://hn.algolia.com/?query=benjojo.co.uk

FiloSottile··on Gandi prices list starting July 13th 2023 [pdf]
https://www.gandi.net/en-US/domain/tld has the old pricing, so a few comparison points.

.com $17.75 → $23.99 (AWS: $13)

.org $17.96 → $24.99 (AWS: $12)

.info $30.77 → $39.99 (AWS: $23)

.it $16.96 → $24.99 (AWS: $15)

.expert $74.86 → $99.99 (AWS: $49)

.training $17.75 → $59.99 (AWS: $27)

FiloSottile··on A Cryptographic Near Miss
Well, this issue was in the assembly, but it was not an assembly issue. It's interesting to think about how we could have encoded the assumptions in a machine-checkable way, because they are actually not unlike the assumptions of some formally verified components.

Here we had: 1) incomplete addition that had to be called with different points; and consequently 2) scalar multiplication that had to be called with a reduced scalar so the computation wouldn't wrap and add two equal points. I don't think we have the tools to encode (1), nor the fact that (2) satisfies (1). (2) maybe could have been encoded in the type system by accepting a ReducedScalar.

FiloSottile··on A Cryptographic Near Miss
Heh, I used to joke that in Go it's safer because I know where the compiler team sits, but I think there's also a fundamental design reason: the Go compiler has speed as a primary goal. I don't know if that's still true, but there used to be a rule of thumb that a new optimization had to speed up the compiler enough to make up for its cost to be added. It's unlikely that unwinding bit masks into branches would be worth adding.

Anyway, we're not moving all cryptography to assembly anytime soon, and I'm positive that would not be a net increase in security, even if it would mitigate the hypothetical risk of compiler-introduced side-channels.

FiloSottile··on A Cryptographic Near Miss
The assembly is there for performance. Other curves are implemented in constant time pure Go. (It's actually more robust than constant time C, because the Go compiler is less creative in "optimizing" things into branches.)
FiloSottile··on Code coverage for Go integration tests
No idea if the technique was original, it’s been too long, but I wrote about it on the Cloudflare blog in 2016. https://blog.cloudflare.com/go-coverage-with-external-tests/

Anyway, very happy to see the team ship first class support for it. It immediately made coverage support in testscript much more natural, too. https://github.com/rogpeppe/go-internal/pull/201

FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
> note that Age uses 10 words in its default, which if using bips list, is 110 bits

That's correct. The passphrase is then fed to scrypt with N = 18, so the total number of operations required for a conventional key search that enumerates possible passphrases is 2^128. I do wonder how hard scrypt is to implement in a QC, I'll look in the literature or ask. Even if scrypt costed zero gates, which seems unlikely since memory accesses are not free, 110 bits Grover would still require ~2^112 gates at MAXDEPTH 2^40.

> I think the industry standard for encryption of data data at rest is AES-256.

Discussions about what is or isn't "industry standard" are hard to have productively because there is no authoritative or technical answer, but I will point out that mail.google.com and Chrome use 128 bits ciphers to talk to each other. Data at rest is not more sensitive than data in transit, the latter can just be recorded by an attacker and cracked in the future.

I agree that compliance usually prefers 256 bits.

FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
Nope, HKDF outputs are always 256 bits. They are used either as a HMAC-SHA-256 key or as a ChaCha20Poly1305 key, so everything downstream of HKDF is 256 bits.

In "Conventions used in this document" you'll find the sentence "The length of the output keying material is always 32 bytes." making this explicit.

FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
Yes, they are broader projects, although it's too early for a proper announcement. They make sense together, hence why CCTV is under C2SP, but they have different motivations.

C2SP is an experiment in producing specifications applying techniques from software development, including semantic versioning and the concept of a maintainer. It was borne out of displeasure with the pace and output of the IETF's CFRG, which is taking years to publish ready-made documents like ristretto255, and makes complex protocols with lots of sharp edges and moving parts, as well as being generally a pain to engage with.

CCTV is a place to pool test vectors, so we don't have to keep reinventing them for each implementation and we can cross-pollinate our test coverage. It's also a place to drop new vectors to test for newly found edge cases or issues. You can think of it as an open Project Wycheproof.

FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
Can I ask what the KMS is, for my informal plugin prioritization/planning? If you prefer to email it, it's hi at my domain, filippo.io.
FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
That makes perfect sense, two weeks is way too early to deploy something in production.

Also, good call on not using openssl(1) in production. Last time I checked that CLI was primarily meant for testing, and anyway is full of sharp edges.

Not sure what AES-256-GCM vs ChaCha20Poly1305 has to do with KMSs though? I ask because age is specifically designed to support pluggable key wrapping mechanisms to support KMSs. You can write a plugin that talks to your KMS to wrap the file key, and use age for everything else. Surely you're not sending the whole file payload to the KMS.

FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
Hi! I read and appreciated your issues and discussions, sorry I didn't get to respond to them yet, but I've been thinking about it.

Although I don't disagree that parsing text is hard, I also think that parsing variable-size binary formats is hard (and there is a tall, tall pile of bugs to confirm that). Really, parsing is hard. Rather than count on one design or the other to be bug-proof, I worked on a large test suite to help implementations catch their parsing bugs. [https://c2sp.org/CCTV/age] I think it would have found one of the issues you reported if that implementation had integrated it, and I am going to add vectors for various resource exhaustion scenarios which I hope would have found the other. (I am not going to look at what it is exactly, so I will know if I made the suite comprehensive enough without being too specific about this bug.)

I also liked your observation that it would have been nice if the header was streamable. [https://github.com/C2SP/C2SP/issues/28] It went on the pile labeled "regrets / for v2 when it comes", thank you.

FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
> If you divide your key search effort by 10 your chances of success are divided by 10 (linear drop off).

Right, but if the starting point is 128 bits it doesn't matter how much you can parallelize the attack, you're not going to find a key regardless of how you divide the key space, even if the chances drop off only linearly.

Again, this is about "good enough". 128 bits of collision security are "better" than 128 bits of "preimage security" (I've never heard resistance against encryption key brute force called preimage security, but I think I get it) in the same way that 256 bits of collision security are better than 128 bits of collision security, or any bigger number is better than a smaller number. Cryptography needs to be secure, not as big as possible.

FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
Thank you for the kind words about my work on Go!

I think there are no standards for the things you mention because there shouldn't be any. If they existed, they would be necessarily complex and bloated like JWT or XML, introducing unneeded complexity in anything that adopted them. age tries to be as much complexity needed for the use case and no more. Other designs can make their different choices for their different use cases. That's good!

No contest on (1). On (2) I want to mention that "recipient" might have been an unfortunate choice of word, but it has nothing to do with email, it just means "a thing that can be encrypted to" like a public key, and any envelope encryption scheme will have something like that even if it doesn't give it this or any name. For (3) I have no idea what your requirements are, but I would claim age is pretty much state of the art (partially because it's not hard, age is trivial by cryptography research standards). Wireguard is being merrily deployed everywhere and uses ChaCha20-Poly1305 as well, FWIW.

(age does have a magic number in the header, and I see you came to realize why metadata in files is a bad idea. It's a bad idea also because it would be attacker-controlled.)

[Edit: s/No context/No contest/]

FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
I've responded to these concerns in my reply to the sister comment. https://news.ycombinator.com/item?id=34949197

FWIW, no cryptographer I know would call 128 bits "sub-standard" and NIST itself is of the opinion that quantum computers will not break 128 bit keys. The links in my other comment get into more details as to why.

I want to mention something about "this issue should be clearly stated in the front page". I've seen this suggestion made many times about many projects, and I disagree with it almost universally, aside from the fact that it's often made about non-issues, such as in this case. Security (and security-relevant) tools should not have issues that need communicating to users, and if they did they should fix them, not delegate a choice to a user. Imagine if every project came with a list of potential issues you have to form an opinion on, and that you're not allowed to complain about because you were warned, after all. It's not a solution! If I thought this was an issue, I would produce a v2 of the spec, and guide users through migrating, instead.

FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
This is a common question! It's a deliberate choice.

The notion of security levels is somewhat in disuse. It's impossible to do any operation, even moving a single electron, 2^128 times so anything that actually has 128 bits of security is "secure enough" for any requirement. This is not a new idea, see agl's post from 2014. [https://www.imperialviolet.org/2014/05/25/strengthmatching.h...] There are arguments that boil down to "more is always better" but I am unconvinced by them as they could be used to argue for 512, 1024, 4096 bit symmetric keys as well, why stop at 256 bits. Part of what changed is that fundamental cryptographic primitives break a lot less than they used to do. "Too much crypto" is a good read about this. [https://eprint.iacr.org/2019/1492]

The only reason to use more than 128 bits of key is to protect against multi-user attacks. That's a situation where an attacker is trying to break one of a very large number of ciphertexts or keys, and would be satisfied with breaking any of them. If you are trying to break one of 2^52 ciphertexts encrypted with 128-bit keys, you can theoretically do it in 2^76 time, which might be doable! (Major asterisks, like that they all need to have encrypted the same plaintext, but anyway.) There are two ways to protect against that: larger keys or nonces. age uses a 128-bit per-file nonce fed into HKDF, making the total search space 128 + 128 = 256 bits, safe in every multi-user scenario, too.

Why use a nonce and not a bigger key? That works out to the same file size overhead! The difference is that the key is repeated for every recipient while the nonce is only serialized once. That means that if a file has 65 recipients, this will let us save about a kilobyte. Is it worth a lot? Not really, but it was free. It also makes most stanza bodies a single line, which is nice.

There's also a misconception that 128 bits are not enough for post-quantum resistance. I also thought that, but it turns out to be based on a simplistic understanding of Grover's algorithm. I wrote about it in the context of age specifically [https://words.filippo.io/dispatches/post-quantum-age/#128-bi...] but if you don't trust me you can also check the very last FAQ on NIST's PQC page. [https://csrc.nist.gov/Projects/post-quantum-cryptography/faq...]

(I am not sure what you mean by X25519's "collision resistance" vs the file key's "preimage resistance". Those are hash function security notions and this is a more complex setting. As you know, X25519 is a key exchange algorithm, not a hash function, and ~128 bits is the amount of work required to reverse the private key into the public key. Anyway, to get a collision in the derived file key, both the key and the nonce would have to collide (128 + 128 = 256 bits) so the "collision resistance" of the whole age scheme is still 128 bits.)

FiloSottile··on Age: Modern file encryption format with multiple pluggable recipients
_o/ hi all, age author here!

The OP link is the spec, here's a few other things you might find interesting

- the Go reference implementation https://age-encryption.org

- the Go library docs https://pkg.go.dev/filippo.io/age

- the CLI man page https://filippo.io/age/age.1

- the large reusable test suite (which I should write about!) https://c2sp.org/CCTV/age

- an interoperable Rust implementation by @str4d https://github.com/str4d/rage

- a YubiKey plugin by @str4d https://github.com/str4d/age-plugin-yubikey

- the draft plugin protocol specification (which we should really merge) https://github.com/C2SP/C2SP/pull/5/files?short_path=07bf8cc...

- a Windows GUI by @spieglt https://github.com/spieglt/winage

- a discussion of the authentication properties of age https://words.filippo.io/dispatches/age-authentication/

- a discussion of a potential post-quantum plugin https://words.filippo.io/dispatches/post-quantum-age/

- a password-store fork that uses age instead of gpg https://github.com/FiloSottile/passage (see also: how I use it with a YubiKey https://words.filippo.io/dispatches/passage/)

(Yes I should make a website to collate all this.) Happy to answer any questions!

FiloSottile··on Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519
Each Write encrypts a separate "record" (in the parlance of TLS and Noise). Each of those records can be arbitrarily dropped, replayed, or reflected.

Here's an example, if you do

    Write("Hello")
    Write(" the password is ")
    Write("password")
then without a key I can make you or your peer read "Hello the password is Hello" (or "HelloHelloHello" or any composition of those messages).

No Noise protocol would allow that.

FiloSottile··on Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519
There is no description of the protocol or of its security goals, so I am making some guesses based on a cursory look at the source and what I imagine this might be for.

A single symmetric key is derived for both directions, and there is no checking of nonces, so as far as I can tell any message can be dropped, reordered, or replayed in both directions. (Including replaying message from A to B as if they were from B to A.) This is a bit like using ECB and likely to lead to fun application-specific attacks like [0].

This is very much rolling your own crypto, in a dangerous way. I am on the record as being "against" the "don't roll your own crypto" refrain [1], but mostly because it doesn't work: it should discourage people from publishing hand-rolled protocols such as this, but instead people think it means "don't roll your own primitives" and accept any use of "Ed25519/X25519" as probably secure.

Please read about the Noise framework [2] to get an idea of how much nuance there is to this, and consider using a Go implementation of it [3] instead.

P.S. This kind of issue is also why I maintain that NaCl is not a high-level scheme [4]: this could have used NaCl and have the exact same issues. libsodium has a couple slightly higher-level APIs that could have helped, secretstream [5] and kx [6], but again please use Noise.

[0] https://cryptopals.com/sets/2/challenges/13

[1] https://securitycryptographywhatever.buzzsprout.com/1822302/...

[2] https://noiseprotocol.org/noise.html

[3] https://github.com/flynn/noise

[4] https://words.filippo.io/dispatches/nacl-api/

[5] https://libsodium.gitbook.io/doc/secret-key_cryptography/sec...

[6] https://libsodium.gitbook.io/doc/key_exchange

FiloSottile··on Enigma: A simple cross-platform encrypted filesystem in Golang
Well, I (and most security and cryptography experts I discussed this with) disagree, and I don’t think we’re going to find a canonical source for what the warning is supposed to mean.

Its broader version that includes protocols and formats easily applies here (although is also arguably defeated because it didn’t stop this project from being published without caveats and making it to the HN front page).

We had a discussion about this with tptacek on his podcast. https://securitycryptographywhatever.buzzsprout.com/1822302/...

FiloSottile··on Enigma: A simple cross-platform encrypted filesystem in Golang
Cryptography Engineering was great for its time but has been outdated for years, which in cryptography doesn’t mean “lacks fancy new stuff” but “we learned the hard way to do things differently”. Serious Cryptography and Real World Cryptography are commonly mentioned as successors.
FiloSottile··on Enigma: A simple cross-platform encrypted filesystem in Golang
(1) and (3), yes. (2) is not about process authentication but about using authenticated encryption that detects tampering.

More broadly, there needs to be a threat model that states what your attacker is capable of.

Even more broadly, I get the impression you’re not an experienced cryptography engineer and you didn’t work with one. Learning is great, but this is not presented with any warnings, which is irresponsible.

FiloSottile··on Enigma: A simple cross-platform encrypted filesystem in Golang
I am usually on the side of “Don’t roll your own crypto” being gatekeeping (at least more than the average engineer), but this kind of project with no notes on threat model, experimental status, authors and reviewers is a real problem.

From a quick read of the README, which is not a rigorous description of the design (what does “computed from the cryptological digest” mean?), it seems this offers no authentication, fails completely if an attacker can observe the same file at two points in time, and there is no analysis of how big a tree can get before the chance of at least one directory having two files with the same nonce becoming significant.

However, it’s presented without caveats, and there’s no way for non-practitioners to assess whether it’s fit for their purposes.

Users might be led to think this is usable in the same scenarios as, say, gocryptfs, when if fact it’s completely insecure for real world use cases like encrypting a home directory to sync it on Dropbox.

FiloSottile··on ‘Assassinated in cold blood’: activist killed protesting Georgia’s ‘Cop City’
Are you basing that assessment on any specific evidence? This article claim there is no video of the incident.

Law enforcement in the US (and many other countries, including others where environmental protesters are often killed) has been know and documented to lie routinely, so is not a reliable source to take on face value.

FiloSottile··on FAA NOTAM System Outage
That's a routine ATCSCC.
FiloSottile··on Sourcehut will blacklist the Go module mirror
Everyone can make their own assessment of what is a reasonable default and what counts as a DoS (and they are welcome to opt-out of any traffic), but note that 4GB per day is 0.3704 Mbps.
FiloSottile··on Sourcehut will blacklist the Go module mirror
I can confirm asking to be excluded from refreshes (which AFAIK is still a standing offer, but I obviously can't speak for the mirror team because I am not at Google anymore) would stop all automated traffic from the mirror, and that sr.ht could send a simple HTTP GET to proxy.golang.org for new tags if it wished not to wait for users to request new versions.
FiloSottile··on U.S. safety agency to consider ban on gas stoves amid health fears
That's not what "ad hominem" means, and you don't seem interested in discussing any systemic dynamic. I am disengaging, have a great day!
FiloSottile··on U.S. safety agency to consider ban on gas stoves amid health fears
Yes. I am saying the whole concept of public health and safety (as well as information security) is based on the observation that you can't just "tell people to change a behavior". It's like saying that electrical rules in building codes are overreach, because people can just avoid touching exposed wires.
← PreviousPage 6 of 22Next →