It would be fantastic if Age (or at least something similar) could become standard on Unix machines. I'd love a more Unix-philosophy following tool than GPG/PGP to be around for encryption. That said, I don't think new standard tools for Unix machines are very common. The closest thing I can think of in the last while is `jq`, but it's not "preinstalled on your machine" kind of standard, just "my script might just use it and expect you to have it" kind of standard.
Omnikron13 11 days ago [-]
People might assume you have ripgrep, or fd, I suppose?
Ultimately, though, I think the importance of having a guarantee that the OS has the complete built-in 'swiss army chainsaw' (to borrow a Perl-ism) just isn't as high priority in the age of modern package managed, dependency graphed, fibre connected always online systems vs. big monolithic beasts that you maybe 'make install' the odd extra piece of software you heard about on usenet, once the 300 baud modem is done bleep-blooping out the source from the CVS repository. =P
That said, we do get new toys, right up to the kernel level; compression algorithms like zstd, hashing algorithms like xxhash, the slow & steady (glacial?) advance of BTRFS features...
If there is demand for something like age, you'd expect it'll filter through into the base of distros, become 'de facto standard', glom onto the kernel, etc. etc. like other stuff people find useful and want, no?
(Even if not, it's written in go, so... 'go install filippo.io/age/cmd/...@latest'? =d
Issues aside, modern lang-specific package managers make it stupidly easy to grab software these days.)
packetlost 20 days ago [-]
Isn't POSIX userspace mostly standardized? We should be pretty conservative with what goes into such a standard, but something like age and jq IMO meet that level of utility to justify it.
jjice 20 days ago [-]
Yeah POSIX standardizes a bunch of tools, mostly the ones you'd expect (cut, cat, file, etc). I agree with the conservative standardization for the most part, but I selfishly would love these more niche tools to be available on a fresh box. Good point though, I just want to be a little lazier in my script writing I guess :)
I guess distros are the next layer over POSIX standard. Distributions have the ability to, mostly arbitrarily, select the default packages they ship in their releases.
ReptileMan 20 days ago [-]
>just "my script might just use it and expect you to have it"
That is one path to standardizing something - using it.
0cf8612b2e1e 20 days ago [-]
Chicken and egg problem. People use sh/bash because it is everywhere and standard. Requires energy to justify using an objectively superior tool if it is not default installed.
I would love if I could count on Just, fish, ripgrep, or any other multitude of tools that improve upon these CLI apis that were invented ad hoc and ossified in the 70s. Paved a lot of cow paths.
dolmen 19 days ago [-]
Perl is everywhere, standard (there is a single implementation, with a strong culture of backward compatibility) and an objectively superior tool.
abdusco 19 days ago [-]
Could zipping the file with a password work as an encryption?
upofadown 20 days ago [-]
Doing one thing and doing it well is all and good, but most people are not interested in having to manually mess around with up to 4 raw keys in the pursuit of that. That's particularly true if you are doing pipes and you don't have any good place to put all those keys.
Most of the time you want to go:
gpg --sign --encrypt file
... and be done with it.
tptacek 20 days ago [-]
This is a little vacuous. Why are you signing? Why are you encrypting? Those are different operations. What are you trying to accomplish? The biggest problem with PGP is that its most popular use cases tend to be people bodging this old clanking command line tool into cryptosystems that (a) PGP wasn't designed for and (b) purpose-built cryptosystems are much better at.
One of the reasons age is so constrained is that the problems best served by direct simple file encryption are quite narrow.
upofadown 19 days ago [-]
>Why are you encrypting?
In any case I can think of, people encrypt things because they want to restrict who can know what those things are.
>Why are you signing?
In the context of encrypted files, you would sign because you want to know if an attacker has modified or more simply just replaced your file. Authenticated encryption is considered more or less standard these days.
>Those are different operations.
Except for niche applications like password storage, most people want/need authentication. Giving someone a raw encryption utility like Age is almost always going to result in a situation where that user is not protected against modification/replacement when they do asymmetrical encryption. That is assuming that they can figure out the keys for even just the encryption.
Well actually it does if the attacker does not have access to the decryption key ... which is very much the normal case. Yes, I know about "surreptitious forwarding" but I consider the idea silly in terms of usability[1].
>asymmetrical encryption is authenticated if you keep your recipient key a secret...
This is an expression of the idea that you can just keep the recipient identity (public key) away from the attacker and prevent them from creating a valid ciphertext. The fundamental issue is that this depends on a poorly specified property of the cryptography. Any protection against an attacker being able to derive the public key is merely accidental. The author of the linked article says:
>I am confident the property holds for the X25519 recipients, and that it would hold for a hypothetical Kyber768+X25519 one,...
... but provides no explicit argument to that effect. ... and then continues:
>...but it's important not to advertise it as an age-wide property.
In practice the recipient identity key will show up on the command line and/or will be kept in an unencrypted file. Age itself treats it as a potentially public value.
If you and the recipient have the ability to share and keep a secret value secret, why use asymmetrical encryption in the first place? Why not put that value in the plaintext as discussed previously in the article? The reason that there is not more research into the security of secret recipient identities is because there is no practical value in such use.
Ciphertext authentication and asymmetric signatures are not the same thing.
19 days ago [-]
FiloSottile 20 days ago [-]
_o/ hi all, age author here! age is the one of my projects that grew most organically into an ecosystem. It's always great to see what people build with it. Happy to answer any questions.
- an official TypeScript implementation https://github.com/FiloSottile/typage (based on libsodium.js in the latest version, and on pure-js Noble libraries on main)
Age is great. I used the rust crate to write an ftp server that encrypts the files before they hit disk (specific use case is having a drop box for my network scanner) and I love the simplicity and composability it provides.
One feature request: it would be awesome to have paraphrase encryption for age private keys.
FiloSottile 20 days ago [-]
Identity files can be passphrase encrypted and cmd/age will transparently ask for the passphrase before using them. Is that what you meant?
Yeah that’s it. Probably just wasn’t supported in the rust age library when I used it. Will double check.
qyckudnefDi5 20 days ago [-]
Have you considered writing passage in Go to integrate age and age-plugin-yubikey as a single binary to make it more convenient to setup and use?
r3mko 19 days ago [-]
Combining Passage, pass-otp, and age into a single Go app has actually been on my personal hobby-project TODO list (but I haven't gotten around to it yet).
Integrating age plugins into this binary is not something I would do, though. Besides the fact that the plugins are separate projects with their own release schedules, they are also in different languages (plugin-yubikey is Rust, plugin-se is Swift, ...), and you would need to fork them anyway for communication. I guess you could bundle the binaries together in a package, and make sure the search path searches for the bundled binaries as a fallback.
nabla9 20 days ago [-]
Maybe I'm dense but I can't figure out howto verify/authenticate encrypted files.
Is there something missing in the documentation.
vaylian 20 days ago [-]
Age is designed for a single purpose: Encryption and decryption of files. To create digital signatures use another specialized tool like minisign instead.
Specialized tools are simpler than one do-it-all tool.
> If you encrypt and then sign, an attacker can strip your signature, replace it with their own, and make it look like they encrypted the file even if they don't actually know the contents.
> If you sign and then encrypt, the recipient can decrypt the file, keep your signature, and encrypt it to a different recipient, making it look like you intended to send the file to them.
upofadown 20 days ago [-]
Both cases assume that the user doesn't understand what a signature means. In either case it means that the signer certified the thing signed. Are paper signatures getting so rare that we are collectively starting to forget this?
PhilipRoman 20 days ago [-]
> make it look like they encrypted the file even if they don't actually know the contents.
I might as well encrypt a message "add $10000 to my account" with the bank's public key, sign it with my own key and send it...
wuiheerfoj 20 days ago [-]
Afaik the x25519 recipient uses chacha20poly1305 which is authenticated
upofadown 20 days ago [-]
Only in the case of symmetrical encryption. Then the authentication is based on the shared secret key.
Age (and its rust implementation Rage) combined with agenix[0] and age.el[1] has made my self-hosted deployment and management so, so easy without compromising security. That, when combined with general NixOS conveniences is why I'm able to self-host at all. If not for these, just the anxiety of having to setup new server in case of whatever loss and the associated time/opportunity loss kept me from dong the same for years.
Anyway, just want to say that Age is great!
P.S. The author also did an analysis of Restic the backup tool [2] which also prompted me to setup nice backup solution for my machines. Pretty cool.
I’ve used git-crypt[0] with great success. It uses git smudge so you never commit secrets if you set it up properly the first time.
Unfortunately, it doesn’t support groups.
For a solution that scales to teams, check out SOPS[1]. You have to do a little more work to be sure that secrets are ignored in the repo but it works reasonably well and is well known.
Transparent support at the editor level (age.el) sounds really nice though.
Can you elaborate on how age (and the downstream packages) has made a difference in your workflows?
sharperguy 20 days ago [-]
With agenix, you can encrypt your secrets, such as API keys, and have them stored in your git repo alongside the system configuration (which in nixos is just a bunch of text files). Then you only need to provision the server with the ed25519 private key corresponding to the pubkey the files were encrypted with, and agenix will automatically decrypt the files on boot and place them in /run/agenix, with the specified access permissions.
fmbb 20 days ago [-]
So you still need a secret when provisioning, and you need to handle change management for that, and storing it securely outside of the git repo. And agenix did not change that workflow, or did it?
e3bc54b2 20 days ago [-]
Yes and no.
I only need to care about my SSH key(s). Which I had to anyway. But now the secrets for all the services (except SSH) lie right besides their config. Any change in one or other is directly visible in git log.
In short, age cut down on the number and types of secrets that I have to manage out of band. Which is very good. It's always easier to be able to remember 2 things (config + SSH keys) than 2+n things (config + SSH keys + whatever secret mechanism any service uses, times number of services).
Foxboron 20 days ago [-]
You could also include SSH keys as public secrets.
So like SOPS, but specific to nix somehow? What is the advantage of the nixy integration here vs the universality of SOPS? Better native integration with NixOS?
t0astbread 19 days ago [-]
To clarify maybe, NixOS puts all configuration and program files it handles in a world-readable object store on disk. If you want to manage secrets on NixOS securely, you have two choices:
- Manage it out of band. That negates all of the benefits of NixOS, at least for those files. (I.e. you would need additional deployment steps, rollback wouldn't work, you would have to stop and migrate system services that depend on those secrets yourself, etc.)
- Encrypt it and only decrypt it on activation (which happens when switching to a new config or on boot). agenix and nix-sops (the premier SOPS/NixOS integration) are two libraries that you can include in your config to do that. With this, the world-readable store only contains encrypted secrets.
Of course with #2 you still have to manage your private keys (age or whatever SOPS uses) out-of-band but that is significantly less work since those aren't expected to change nearly as much. You can also generally decouple that from your day-to-day deployment workflow.
SOLAR_FIELDS 19 days ago [-]
I see. So you do need one of these libraries if you want to do things The Nix Way with secrets
e3bc54b2 20 days ago [-]
Similar to sops in a sense that both allow encryption/decryption with SSH keys.
In terms of NixOS integration, both are on equal footing.
I'm just unfond of yaml is all.
stavros 19 days ago [-]
I use git-crypt for this, and love it.
zelphirkalt 20 days ago [-]
Server deployment/management tools like Ansible have their own file encryption and string encryption tools builtin.
max-privatevoid 20 days ago [-]
But then you'd have to use YAML
zelphirkalt 20 days ago [-]
I concur, that is an unfortunate side-effect. The only thing you can then do is to treat yaml as a thing that is constantly out to get you. Make all values strings and use things like > or >- to write strings without having to escape quotes, don't rely on any referencing, except for Ansible's templating itself. Do not code in yaml. Or, if you really want to, perhaps you could even write yaml like json, since json should be accepted format for yaml files.
worldsayshi 20 days ago [-]
Coming from Ansible I can understand the distrust in yaml. But I haven't seen half as much yaml weirdness in Kubernetes (and i associate age/sops with k8s). At least not since I stopped making my own helm charts.
turboponyy 20 days ago [-]
More notably, then you'd have to use Ansible.
shlant 20 days ago [-]
any suggestions on a better config management tool?
max-privatevoid 20 days ago [-]
NixOS
shlant 19 days ago [-]
yea... don't really want to have to change OS for a CM tool
ElectricalUnion 20 days ago [-]
If the thing accepts YAML it often also accepts a equivalent JSON.
valczir 20 days ago [-]
yaml is a superset of json, so by definition anything that accepts yaml _must_ accept json
sharperguy 20 days ago [-]
I have been using agenix and it is very helpful. I am also looking into writing a system module that makes it easy to generate secrets on the fly.
A lot of secrets are just things like, backend and frontend of some service need to be configured with matching keys, but are both running on the same device. In that case you could have a systemd service which just generates a new random key if it doesn't already exist, and then ensure that the dependent services wait for that service to complete. That way you don't have to store anything in git for those at least.
I know there are specialized backup tools like restic or borg, but I like to keep things simple.
Is using age like this to encrypt my files before uploading them to untrusted cloud storage not ok?
tar > age > cloud
Some comments mention signing with minisign. Should I be doing that like this:
tar > age > minisign > cloud
WhyNotHugo 20 days ago [-]
If you make a second backup tomorrow, you'll end up with a new (huge) encrypted tar. restic handles deltas when creating a second backup, and writes new files so that tools like rsync or rclone have to do less work to upload the new data.
That said, I don't see anything strictly _wrong_ with your approach.
qyckudnefDi5 20 days ago [-]
No deduplication is a tradeoff I'm willing to make for simplicity and less things that can go wrong :)
tptacek 20 days ago [-]
Use specialized backup tools! There are cryptographic constructions designed specifically for backup. You will get better backup and better encryption.
qyckudnefDi5 20 days ago [-]
"Better backup" aside, as I understand that I'd miss out on deduplication and all the other things backup software can do like keeping track of what it has backed up etc.
"Better encryption": Can you explain why age's encryption isn't sufficient if it's recommended for encrypting files? Really want to understand how it's recommended for encrypting and sharing a file over an untrusted channel like email, but not recommended to encrypt a file and upload it to an untrusted server.
16 days ago [-]
arcxi 19 days ago [-]
I made a tiny shell script that combines tar+age, you may find it useful for simplicity
Age is good at what it does, but note that afaik you probably should almost always pair it with something like signify[1], because age doesn't have integrity/authenticity verification (by design).
Age is a much better experience than PGP/GPG, even though it only has a subset of GPG's features.
The option and argument handling is intuitive; it makes sense instantly. It gives a more grounded understanding of what's happening with the encryption process, especially because of the short-form recipient format.
Also, setting it up with a Yubikey and Passage (a GNU pass alternative for Age) was a breeze.
Comma2976 20 days ago [-]
>$this is a much better experience than $that, even though it only has a subset of $that's features
I concur, and:
sed 's/even though/because'
20 days ago [-]
lf-non 20 days ago [-]
There is also an official typescript implementation [1] and sops supports it natively [2].
It'd be like naming your software fukr and then insisting "no no no, the R is pronounced 'are', not 'er'."
kitd 20 days ago [-]
Git' is a preexisting word; it'd be pretty strange to pronounce it with a soft G.
It certainly was when I heard it.
gjvc 19 days ago [-]
I work with a French guy who uses "szheet"
stavros 19 days ago [-]
As opposed to "age"?
thaumasiotes 19 days ago [-]
No, "age" is not only a preexisting word, it's one that's common as dirt.
Having the rust port be "rage" only compounds the problem.
The author's rather Italian-looking name tends to suggest that he wouldn't view a hard G as a possibility for the word "age" either (and the pronunciation link specifically goes to a synthetic Italian pronunciation of the word "aghe"...), so something else is going on.
stavros 19 days ago [-]
I don't understand how the author wants to pronounce it. "ag-ay"? It's very confusing that it's an extremely common word which this program decides to pronounce differently.
ljlolel 20 days ago [-]
Or Coq?
20 days ago [-]
nvy 20 days ago [-]
Coq is pronounced exactly how it looks. It's the French word for rooster and for the language, comes from part of the guy's name.
>Kryptor uses strong, fast, and modern cryptographic algorithms, offering post-quantum security. It also addresses security limitations of tools like age and Minisign.
>Unlike most tools, Kryptor limits metadata by using an indistinguishable from random encrypted file format. Encrypted files have no identifiable headers and are randomly padded. File names can also be encrypted.
And from their Secure section [1]:
>Private key encryption for protection at rest, unlike age.
An Age key can be in a PIV slot of a Yubikey. With a secret manager such as Passage, you will have secure access to secrets.
jmprspret 20 days ago [-]
I'd never heard of this. Looks very very interesting!
I'd be keen to know Filippo's (age creator) opinion on this, if he has any.
FiloSottile 20 days ago [-]
Thanks for sharing, always happy when my projects inspire alternatives addressing different parts of the design space. Here are a few quick comments based on skimming the documentation, let me know if I misinterpreted anything.
- signing support
This has always been a non-goal for age. It makes the UX significantly more complex, but it's good if different tools have different goals.
I can't quite make out from https://www.kryptor.co.uk/specification if it does proper signcryption, sign-then-encrypt (vulnerable to signature stripping and re-signing), or encrypt-then-sign (vulnerable to decrypt-reencrypt-forward, like OpenPGP). If the latter two, it's a missed opportunity to offer more security than age+minisign can offer and I encourage the author to look into it!
As https://www.kryptor.co.uk/security-limitations#post-quantum-... acknowledges, "the asymmetric algorithms in Kryptor aren't post-quantum secure". There is support for adding a pre-shared symmetric key, although I did not find the pre-shared key in the usage section, but I would argue that is not asymmetric encryption.
In this sense, I would actually argue that Kryptor is just as post-quantum secure as age: age's symmetric encryption (the passphrase mode) is post-quantum (see https://words.filippo.io/dispatches/post-quantum-age/). We don't support adding a pre-shared symmetric key to asymmetric encryption, but if you have a secure channel to establish a pre-shared key, you should just use passphrase mode.
This is a pretty wonky topic. age as a whole is key committing (you can't make a file that decrypts with two age identities as different plaintexts, some academic researchers tried!). Our file key encryption is not (https://github.com/FiloSottile/age/commit/2194f6962c8bb3bca8...) which means that if you host an online service that accepts an age file and decrypts it with a passphrase and returns an error if it's incorrect, an attacker can do a bruteforce two passphrases at a time instead of one at a time. Given the online oracle is already unusual as a setting, I am not interested in adding complexity to solve this one.
It's not the default because most threat models don't need it: if you have FDE, who's an attacker that can read files from your disk but not replace the age binary in $PATH?
- indistinguishability from random
Not an age goal, actually we very intentionally put "age-encryption.org/v1" in the header so you can run file(1), and specify the type of the recipients to help plugins disambiguate files. The default recipient type doesn't leak any other metadata (i.e. you can't link age files encrypted to the same recipient).
- size padding
This is a good idea and slated for age v2.
colmmacc 20 days ago [-]
Massive fan of age and congrats on its success!! On size padding, I know you've patiently listened to me before on this, but I'll always take a chance to advocate for an approach like PURBs ( https://petsymposium.org/2019/files/papers/issue4/popets-201... ).
Let's say you're in a country that suppresses certain material, like copies of the Bible, or the Hacker Manifesto, or whatever; if the authorities find an encrypted file that closely matches the size of that material; that could do you in. But maybe a more realistic case is how the size of maps tiles alone is enough to figure out where you are looking on a map (https://ioactive.com/ssl-traffic-analysis-on-google-maps/), or the size of streaming video segments (https://www.cs.cornell.edu/~shmat/shmat_usenix17.pdf) gives away what you are watching. Both real-world examples of size side-channels. It's not un-imaginable that someone could use a tool like age to build bigger systems like that, where the leaks creep in.
FiloSottile 20 days ago [-]
My age v2 note for padding says “use Padmé, see Colm’s comments” :)
I’m not really sold on the UR part of PURBs, though: age wants to avoid asking for a passphrase if the file is not passphrase encrypted, and age-plugin-yubikey wants to avoid asking for a PIN if it’s for the wrong YubiKey. These are tradeoffs and it’s not obvious the very end of the spectrum (uniform random) is the right spot.
other than inelegance and the computational overhead, is there a reason why sign then encrypt then sign wouldn't work for this?
FiloSottile 20 days ago [-]
Assuming that implementation never skip verifying the second signature, and compare the signing keys, that should be ok.
20 days ago [-]
lrvick 20 days ago [-]
For someone that never ever needs signing or authentication, including for ones own backups, who never has malware in their threat model, and trusts this specless tool will be maintained forever, maybe this makes sense?
Even then openssl or sq can solve the problem in the same number of commands but with sntabdards.
Most people are best off going with a modern implementation of the PGP standard, ideally via a smart card to protect you from key exfil via malware.
Tools like Keyfork, Sequoia, and/or openpgp-card-tool are almost certainly what you want for most personal signing, encryption, and authentication use cases.
You get broad compatibility with many many different tools.
dpatterbee 20 days ago [-]
> trusts this specless tool will be maintained forever
As per the third sentence of the readme there indeed is a spec[0]. There is also an alternative implementation in the form of rage[1], as well as numerous others listed on the awesome-age page[2].
Age uses standard (and modern) cryptography, and is itself standardized[1].
This is in contrast to the PGP ecosystem, which is infamously fragmented and insistent on maintaining support for insecure and home-baked schemes (e.g. 4880’s weird custom CFB mode). Sequoia has made some progress on the UX side of things, but PGP is a dead horse as far as modern, even conservative cryptographic software design goes.
> Even then openssl or sq can solve the problem in the same number of commands but with sntabdards.
Using OpenSSL to properly encrypt a file is next to impossible, and if you actually succeed at doing so, you’re very unlikely to be following a defined standard.
I’m not familiar with sq.
> modern implementation of the PGP standard
The PGP standard is an unmitigated disaster.
e12e 20 days ago [-]
> I’m not familiar with sq.
The reimplantation of PGP as a clean rust implantation with a simple cli (sq) is imnho quite exiting:
I do think perhaps it's too little too late - bit in contrast with age it does provide for signing and authentication as well as simple(-ish) key/certificate management.
Retr0id 20 days ago [-]
Age is not specless.
20 days ago [-]
glub103011 19 days ago [-]
[dead]
isoprophlex 20 days ago [-]
[flagged]
jrflowers 20 days ago [-]
So it is pronounced kind of like “egg”, Aygg
aboardRat4 20 days ago [-]
[flagged]
packetlost 20 days ago [-]
gnupg is a usability dumpsterfire with tons of footguns everywhere. Very very few people should use gnupg in its current form.
micklemeal 20 days ago [-]
[flagged]
20 days ago [-]
quectophoton 20 days ago [-]
The description claims it's "secure", but nothing pops up in the README when I Ctrl+F `audit`.
So maybe take the "secure" claims with a grain of salt.
tptacek 20 days ago [-]
This drives me a little nuts. There are something like 4 firms† in the world generally recognized as qualified for assessing cryptosystems, against dozens well-known and qualified to audit software but not cryptography. Cryptography is a rare specialty for software security people. How were you going to know whether an "audit" for age was meaningful?
† and, to be fair, dozens of independent practitioners
quectophoton 20 days ago [-]
Oof, yeah maybe "audit" was the wrong word if it causes a reaction this strong.
I just wanted to say it would be nice to know what makes this implementation secure other than the creator's own words about their own project.
(EDIT: Though I guess you coming out to defend it is good enough signal to vouch in favor of it.)
samatman 20 days ago [-]
The description claims these curves are "safe" but nothing pops up when I Ctrl+F `audit`. https://safecurves.cr.yp.to
quectophoton 20 days ago [-]
It's a good observation, but probably a bad example since that page is clear on what criteria they consider for something to be "safe".
That aside, of course DJB would choose criteria that let him label his own curve as "safe".
I'm no cryptographer so ultimately I have no choice but to rely on others' expertise, but that does not mean I take at face value the words of someone talking about their own project. Probably for the same reason HN requires disclosure when talking about something you're involved in.
klabb3 20 days ago [-]
Meh. The author of age is very experienced and known specifically for security, crypto and within the implementation language (Go).
Audits are only as good as the competence of the auditors and can often turn into checklist rituals. It certainly doesn’t hurt, but audits are not a panacea.
Ferret7446 19 days ago [-]
What if the author has become malicious or is being blackmailed? N+1, N+2 is a common expectation in many fields (science replication, all manner of independent audits/investigations, nuclear launch codes, etc).
quectophoton 20 days ago [-]
Agreed, but IMHO claiming that a crypto library is secure without providing independent verification, is like claiming something is fast without providing benchmarks. (And both are the same in the sense that neither is a panacea.)
I'm only bringing up audits because such claim was made, but maybe I should have said "independent verification" instead since it's more general.
klabb3 20 days ago [-]
Sure, I think we agree in semantics but the wording is difficult. The bar for secure you’re referring to is quite high, a lot of commercial products that brand themselves secure would be much less secure than something like age. These days I think it’s fair to use “secure” in the sense of “made a serious effort to provide certain security properties”. It’s too hard to define, let alone agree, to what secure should mean for everyone.
> Today, I maintain the cryptography packages that ship as part of the Go standard library (crypto/… and golang.org/x/crypto/…), including the TLS, SSH, and low-level implementations, such as elliptic curves, RSA, and ciphers. These packages are critical to virtually every Go application, securing HTTPS requests, implementing authentication, and providing encryption.
quectophoton 20 days ago [-]
I'm no cryptographer so I might be misunderstanding how all this works (also why I have to rely on whatever signal I can catch instead of just reviewing the code myself like with other more mundane dependencies), but it was my impression that in cryptography things were to be considered with skepticism until at least someone else (emphasis on "someone else") with good enough credentials/skills had attempted to break it at least once.
eximius 20 days ago [-]
Because the vast majority of new works are not done by one of the few who would be qualified to check it.
You can think of the cryptography community as similar to the math community. If some nobody makes a new proof of a big conjecture, it is considered with skepticism until some big name comes around to verify it. If Terence Tao comes out with a new proof in one of his specialities, people are going to assume it's basically correct or will have only very minor errors that are easily fixed.
quectophoton 20 days ago [-]
Makes sense, I see where I went wrong now, thanks for taking the time to explain.
tantalor 20 days ago [-]
Sounds like a false analogy.
"independent verification" is subjective. Who does the verification, do you trust them, how do you know they didn't screw up.
"benchmarks" are objective. A is faster than B, we know because of the way that it is.
Rendered at 11:27:39 GMT+0000 (Coordinated Universal Time) with Vercel.
Ultimately, though, I think the importance of having a guarantee that the OS has the complete built-in 'swiss army chainsaw' (to borrow a Perl-ism) just isn't as high priority in the age of modern package managed, dependency graphed, fibre connected always online systems vs. big monolithic beasts that you maybe 'make install' the odd extra piece of software you heard about on usenet, once the 300 baud modem is done bleep-blooping out the source from the CVS repository. =P
That said, we do get new toys, right up to the kernel level; compression algorithms like zstd, hashing algorithms like xxhash, the slow & steady (glacial?) advance of BTRFS features...
If there is demand for something like age, you'd expect it'll filter through into the base of distros, become 'de facto standard', glom onto the kernel, etc. etc. like other stuff people find useful and want, no?
(Even if not, it's written in go, so... 'go install filippo.io/age/cmd/...@latest'? =d Issues aside, modern lang-specific package managers make it stupidly easy to grab software these days.)
I've always used this site as reference: https://pubs.opengroup.org/onlinepubs/9699919799/
That is one path to standardizing something - using it.
I would love if I could count on Just, fish, ripgrep, or any other multitude of tools that improve upon these CLI apis that were invented ad hoc and ossified in the 70s. Paved a lot of cow paths.
Most of the time you want to go:
... and be done with it.One of the reasons age is so constrained is that the problems best served by direct simple file encryption are quite narrow.
In any case I can think of, people encrypt things because they want to restrict who can know what those things are.
>Why are you signing?
In the context of encrypted files, you would sign because you want to know if an attacker has modified or more simply just replaced your file. Authenticated encryption is considered more or less standard these days.
>Those are different operations.
Except for niche applications like password storage, most people want/need authentication. Giving someone a raw encryption utility like Age is almost always going to result in a situation where that user is not protected against modification/replacement when they do asymmetrical encryption. That is assuming that they can figure out the keys for even just the encryption.
Well actually it does if the attacker does not have access to the decryption key ... which is very much the normal case. Yes, I know about "surreptitious forwarding" but I consider the idea silly in terms of usability[1].
>asymmetrical encryption is authenticated if you keep your recipient key a secret...
This is an expression of the idea that you can just keep the recipient identity (public key) away from the attacker and prevent them from creating a valid ciphertext. The fundamental issue is that this depends on a poorly specified property of the cryptography. Any protection against an attacker being able to derive the public key is merely accidental. The author of the linked article says:
>I am confident the property holds for the X25519 recipients, and that it would hold for a hypothetical Kyber768+X25519 one,...
... but provides no explicit argument to that effect. ... and then continues:
>...but it's important not to advertise it as an age-wide property.
In practice the recipient identity key will show up on the command line and/or will be kept in an unencrypted file. Age itself treats it as a potentially public value.
If you and the recipient have the ability to share and keep a secret value secret, why use asymmetrical encryption in the first place? Why not put that value in the plaintext as discussed previously in the article? The reason that there is not more research into the security of secret recipient identities is because there is no practical value in such use.
[1] https://articles.59.ca/doku.php?id=pgpfan:forwarding
Here are some previous discussions
132 points on Feb 26, 2023 | 77 comments | https://news.ycombinator.com/item?id=34936504
126 points on Sept 26, 2022 | 54 comments | https://news.ycombinator.com/item?id=32980141
113 points on June 11, 2022 | 33 comments | https://news.ycombinator.com/item?id=31705670
494 points on Sept 6, 2021 | 88 comments | https://news.ycombinator.com/item?id=28435613
466 points on Dec 27, 2019 | 199 comments | https://news.ycombinator.com/item?id=21895671
and here some related resources
- a list of age ecosystem projects https://github.com/FiloSottile/awesome-age
- the format specification https://c2sp.org/age
- 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
- an official TypeScript implementation https://github.com/FiloSottile/typage (based on libsodium.js in the latest version, and on pure-js Noble libraries on main)
- a YubiKey plugin by @str4d https://github.com/str4d/age-plugin-yubikey
- the plugin protocol specification https://c2sp.org/age-plugin
- 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 the plugin architecture https://words.filippo.io/dispatches/age-plugins/
- 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/)
One feature request: it would be awesome to have paraphrase encryption for age private keys.
https://github.com/FiloSottile/age?tab=readme-ov-file#passph...
Integrating age plugins into this binary is not something I would do, though. Besides the fact that the plugins are separate projects with their own release schedules, they are also in different languages (plugin-yubikey is Rust, plugin-se is Swift, ...), and you would need to fork them anyway for communication. I guess you could bundle the binaries together in a package, and make sure the search path searches for the bundled binaries as a fallback.
Is there something missing in the documentation.
Specialized tools are simpler than one do-it-all tool.
> If you encrypt and then sign, an attacker can strip your signature, replace it with their own, and make it look like they encrypted the file even if they don't actually know the contents.
> If you sign and then encrypt, the recipient can decrypt the file, keep your signature, and encrypt it to a different recipient, making it look like you intended to send the file to them.
I might as well encrypt a message "add $10000 to my account" with the bank's public key, sign it with my own key and send it...
Do you have an opinion or comment on this? https://news.ycombinator.com/item?id=41159236
Anyway, just want to say that Age is great!
P.S. The author also did an analysis of Restic the backup tool [2] which also prompted me to setup nice backup solution for my machines. Pretty cool.
[0]: https://github.com/ryantm/agenix
[1]: https://github.com/anticomputer/age.el
[2]: https://words.filippo.io/restic-cryptography/
Unfortunately, it doesn’t support groups.
For a solution that scales to teams, check out SOPS[1]. You have to do a little more work to be sure that secrets are ignored in the repo but it works reasonably well and is well known.
Transparent support at the editor level (age.el) sounds really nice though.
[0] https://github.com/AGWA/git-crypt
[1] https://github.com/getsops/sops
[0] https://github.com/AGWA/git-crypt
[1] https://github.com/getsops/sops
I only need to care about my SSH key(s). Which I had to anyway. But now the secrets for all the services (except SSH) lie right besides their config. Any change in one or other is directly visible in git log.
In short, age cut down on the number and types of secrets that I have to manage out of band. Which is very good. It's always easier to be able to remember 2 things (config + SSH keys) than 2+n things (config + SSH keys + whatever secret mechanism any service uses, times number of services).
https://github.com/Foxboron/ssh-tpm-agent
- Manage it out of band. That negates all of the benefits of NixOS, at least for those files. (I.e. you would need additional deployment steps, rollback wouldn't work, you would have to stop and migrate system services that depend on those secrets yourself, etc.)
- Encrypt it and only decrypt it on activation (which happens when switching to a new config or on boot). agenix and nix-sops (the premier SOPS/NixOS integration) are two libraries that you can include in your config to do that. With this, the world-readable store only contains encrypted secrets.
Of course with #2 you still have to manage your private keys (age or whatever SOPS uses) out-of-band but that is significantly less work since those aren't expected to change nearly as much. You can also generally decouple that from your day-to-day deployment workflow.
In terms of NixOS integration, both are on equal footing.
I'm just unfond of yaml is all.
A lot of secrets are just things like, backend and frontend of some service need to be configured with matching keys, but are both running on the same device. In that case you could have a systemd service which just generates a new random key if it doesn't already exist, and then ensure that the dependent services wait for that service to complete. That way you don't have to store anything in git for those at least.
Is using age like this to encrypt my files before uploading them to untrusted cloud storage not ok?
tar > age > cloud
Some comments mention signing with minisign. Should I be doing that like this:
tar > age > minisign > cloud
That said, I don't see anything strictly _wrong_ with your approach.
"Better encryption": Can you explain why age's encryption isn't sufficient if it's recommended for encrypting files? Really want to understand how it's recommended for encrypting and sharing a file over an untrusted channel like email, but not recommended to encrypt a file and upload it to an untrusted server.
https://github.com/arcxio/urn/blob/main/urn
You may expect tools such as restic or Borg or rclone should use Age. But they don’t, because they need their own file formats.
Restic is excellent. I can’t recommend it enough.
https://www.latacora.com/blog/2020/03/12/the-soc-starting/
https://www.latacora.com/blog/2019/07/16/the-pgp-problem/
[1] https://man.openbsd.org/signify.1
[1] https://github.com/jedisct1/minisign
The option and argument handling is intuitive; it makes sense instantly. It gives a more grounded understanding of what's happening with the encryption process, especially because of the short-form recipient format.
Also, setting it up with a Yubikey and Passage (a GNU pass alternative for Age) was a breeze.
I concur, and:
sed 's/even though/because'
[1] https://github.com/FiloSottile/typage
[2] https://github.com/getsops/sops?tab=readme-ov-file#encryptin...
Lol, or 'git' according to one of my more sensitive colleagues.
https://en.wiktionary.org/wiki/git#Etymology_1
https://en.wiktionary.org/wiki/git#Etymology_2
It'd be like naming your software fukr and then insisting "no no no, the R is pronounced 'are', not 'er'."
It certainly was when I heard it.
Having the rust port be "rage" only compounds the problem.
The author's rather Italian-looking name tends to suggest that he wouldn't view a hard G as a possibility for the word "age" either (and the pronunciation link specifically goes to a synthetic Italian pronunciation of the word "aghe"...), so something else is going on.
It's also the English word for rooster.
From their FAQ [0]:
>Kryptor uses strong, fast, and modern cryptographic algorithms, offering post-quantum security. It also addresses security limitations of tools like age and Minisign.
>Unlike most tools, Kryptor limits metadata by using an indistinguishable from random encrypted file format. Encrypted files have no identifiable headers and are randomly padded. File names can also be encrypted.
And from their Secure section [1]:
>Private key encryption for protection at rest, unlike age.
[0]: https://www.kryptor.co.uk/faq#why-should-i-use-kryptor-over-...
[1]: https://www.kryptor.co.uk/#secure
An Age key can be in a PIV slot of a Yubikey. With a secret manager such as Passage, you will have secure access to secrets.
I'd be keen to know Filippo's (age creator) opinion on this, if he has any.
- signing support
This has always been a non-goal for age. It makes the UX significantly more complex, but it's good if different tools have different goals.
I can't quite make out from https://www.kryptor.co.uk/specification if it does proper signcryption, sign-then-encrypt (vulnerable to signature stripping and re-signing), or encrypt-then-sign (vulnerable to decrypt-reencrypt-forward, like OpenPGP). If the latter two, it's a missed opportunity to offer more security than age+minisign can offer and I encourage the author to look into it!
- sender authentication
I wrote about this. tl;dr age has authentication, but I am not sure what a non-sharp UX around it would be, so I don't advertise it. https://words.filippo.io/dispatches/age-authentication/
- post-quantum security
As https://www.kryptor.co.uk/security-limitations#post-quantum-... acknowledges, "the asymmetric algorithms in Kryptor aren't post-quantum secure". There is support for adding a pre-shared symmetric key, although I did not find the pre-shared key in the usage section, but I would argue that is not asymmetric encryption.
In this sense, I would actually argue that Kryptor is just as post-quantum secure as age: age's symmetric encryption (the passphrase mode) is post-quantum (see https://words.filippo.io/dispatches/post-quantum-age/). We don't support adding a pre-shared symmetric key to asymmetric encryption, but if you have a secure channel to establish a pre-shared key, you should just use passphrase mode.
age does have a third-party fully post-quantum asymmetric encryption plugin (https://github.com/keisentraut/age-plugin-sntrup761x25519) and I plan to make an ML-KEM one once the standard is out.
- key commitment
This is a pretty wonky topic. age as a whole is key committing (you can't make a file that decrypts with two age identities as different plaintexts, some academic researchers tried!). Our file key encryption is not (https://github.com/FiloSottile/age/commit/2194f6962c8bb3bca8...) which means that if you host an online service that accepts an age file and decrypts it with a passphrase and returns an error if it's incorrect, an attacker can do a bruteforce two passphrases at a time instead of one at a time. Given the online oracle is already unusual as a setting, I am not interested in adding complexity to solve this one.
- private key encryption
age supports that! https://github.com/FiloSottile/age?tab=readme-ov-file#passph...
It's not the default because most threat models don't need it: if you have FDE, who's an attacker that can read files from your disk but not replace the age binary in $PATH?
- indistinguishability from random
Not an age goal, actually we very intentionally put "age-encryption.org/v1" in the header so you can run file(1), and specify the type of the recipients to help plugins disambiguate files. The default recipient type doesn't leak any other metadata (i.e. you can't link age files encrypted to the same recipient).
- size padding
This is a good idea and slated for age v2.
Let's say you're in a country that suppresses certain material, like copies of the Bible, or the Hacker Manifesto, or whatever; if the authorities find an encrypted file that closely matches the size of that material; that could do you in. But maybe a more realistic case is how the size of maps tiles alone is enough to figure out where you are looking on a map (https://ioactive.com/ssl-traffic-analysis-on-google-maps/), or the size of streaming video segments (https://www.cs.cornell.edu/~shmat/shmat_usenix17.pdf) gives away what you are watching. Both real-world examples of size side-channels. It's not un-imaginable that someone could use a tool like age to build bigger systems like that, where the leaks creep in.
I’m not really sold on the UR part of PURBs, though: age wants to avoid asking for a passphrase if the file is not passphrase encrypted, and age-plugin-yubikey wants to avoid asking for a PIN if it’s for the wrong YubiKey. These are tradeoffs and it’s not obvious the very end of the spectrum (uniform random) is the right spot.
other than inelegance and the computational overhead, is there a reason why sign then encrypt then sign wouldn't work for this?
Even then openssl or sq can solve the problem in the same number of commands but with sntabdards.
Most people are best off going with a modern implementation of the PGP standard, ideally via a smart card to protect you from key exfil via malware.
Tools like Keyfork, Sequoia, and/or openpgp-card-tool are almost certainly what you want for most personal signing, encryption, and authentication use cases.
You get broad compatibility with many many different tools.
As per the third sentence of the readme there indeed is a spec[0]. There is also an alternative implementation in the form of rage[1], as well as numerous others listed on the awesome-age page[2].
[0]: https://github.com/C2SP/C2SP/blob/main/age.md
[1]: https://github.com/str4d/rage
[2]: https://github.com/FiloSottile/awesome-age
This is in contrast to the PGP ecosystem, which is infamously fragmented and insistent on maintaining support for insecure and home-baked schemes (e.g. 4880’s weird custom CFB mode). Sequoia has made some progress on the UX side of things, but PGP is a dead horse as far as modern, even conservative cryptographic software design goes.
[1]: https://github.com/C2SP/C2SP/blob/main/age.md
Using OpenSSL to properly encrypt a file is next to impossible, and if you actually succeed at doing so, you’re very unlikely to be following a defined standard.
I’m not familiar with sq.
> modern implementation of the PGP standard
The PGP standard is an unmitigated disaster.
The reimplantation of PGP as a clean rust implantation with a simple cli (sq) is imnho quite exiting:
https://sequoia-pgp.gitlab.io/sq-user-guide/
I do think perhaps it's too little too late - bit in contrast with age it does provide for signing and authentication as well as simple(-ish) key/certificate management.
So maybe take the "secure" claims with a grain of salt.
† and, to be fair, dozens of independent practitioners
I just wanted to say it would be nice to know what makes this implementation secure other than the creator's own words about their own project.
(EDIT: Though I guess you coming out to defend it is good enough signal to vouch in favor of it.)
That aside, of course DJB would choose criteria that let him label his own curve as "safe".
I'm no cryptographer so ultimately I have no choice but to rely on others' expertise, but that does not mean I take at face value the words of someone talking about their own project. Probably for the same reason HN requires disclosure when talking about something you're involved in.
Audits are only as good as the competence of the auditors and can often turn into checklist rituals. It certainly doesn’t hurt, but audits are not a panacea.
I'm only bringing up audits because such claim was made, but maybe I should have said "independent verification" instead since it's more general.
Have you seen Filippo's credentials? He's overwhelmingly qualified for this. https://github.com/FiloSottile
> Today, I maintain the cryptography packages that ship as part of the Go standard library (crypto/… and golang.org/x/crypto/…), including the TLS, SSH, and low-level implementations, such as elliptic curves, RSA, and ciphers. These packages are critical to virtually every Go application, securing HTTPS requests, implementing authentication, and providing encryption.
You can think of the cryptography community as similar to the math community. If some nobody makes a new proof of a big conjecture, it is considered with skepticism until some big name comes around to verify it. If Terence Tao comes out with a new proof in one of his specialities, people are going to assume it's basically correct or will have only very minor errors that are easily fixed.
"independent verification" is subjective. Who does the verification, do you trust them, how do you know they didn't screw up.
"benchmarks" are objective. A is faster than B, we know because of the way that it is.