Ask HN: Is there a portable encryption file format?

5 points by binwiederhier ↗ HN
Even after a lot of research, I wasn't able to find an encryption file format that is widely used and still considered "supported" on most platforms. The obvious answer is OpenPGP [1], but that's widely considered "not modern" and some languages even deprecate their support for it (e.g. Go [2]).

Specifically, I'm looking for a container format like OpenPGP that can support different cipher suites, e.g. "passphrase-to-key via PBKDF2, then AES-GCM-128" or similar and is portable across different programming languages and operating systems.

I do not believe such a tool exists, but I'm scratching my head as to why. It's 2022. TLS is ubiquitous. Why is there no TLS-in-a-file?

My use case is my push notification project [3]. I want people to be able to do this (on the shell):

   echo "secret message" | encxyz -p "password" | curl -T- ntfy.sh/mytopic
Or this (in JS):

   import {xyz_encyrpt} from "encryptxyz";
   const message = xyz_encrypt("secret message", "password");
   fetch(...);
Of course I can design my own thing (and I have), but then I have to make my own libraries for all languages that I want to offer end-to-end encryption for.

[1] https://datatracker.ietf.org/doc/html/rfc4880

[2] https://github.com/golang/go/issues/44226

[3] https://github.com/binwiederhier/ntfy

13 comments

[ 4.7 ms ] story [ 46.3 ms ] thread
In MacOS or Linux, you can use openssl on the CLI easily.

$ echo -n "private-message" | openssl enc -e -aes-256-cbc -a -salt enter aes-256-cbc encryption password: Verifying - enter aes-256-cbc encryption password:

Then to decrypt echo 'U2Fsxxxxxxxxxx' | openssl aes-256-cbc -a -d -salt

I think the CLI is not the problem. More that there is a maintained implementation in Ruby, Rust, Go, JS, PHP, .... You get the idea.

I suppose openssl is supported in all of them, but it only provides primitives. I still have to manually define a file format to store the salt and such.

https://www.aescrypt.com/

Open Source encryption using the industry standard Advanced Encryption Standard (AES) to easily and securely encrypt files on Windows, Mac, Linux, Android, iOS and more.

While interesting, I think it looks quite unmaintained (mailing list is from 2019, docs update from 2013), and also I'm pretty sure it's not free software or even an open spec either. Sadly, looks cool.
Did you bother to read the web site?

You are free to use this software in your business, at home, or in your own open source development projects.

AES is a NIST standard so it is open spec, open source, free as in beer and speech. As for maintenance, the lack of it can be a good thing. This may mean none was required --- no bugs have been found.

My apologies. It does say that it's open source on the website, you are right. I merely looked at the GitHub repository and that says at the bottom that it's retired and old code. And i couldn't find any new code posted.

Also, AES is an open standard yes. I was however talking about the file format that it it structures its files as. That is very much non trivial since there are salts, IVs, mode of operation, the actual cipher, ...

I was however talking about the file format that it it structures its files as.

Fully documented on the web site.

> but then I have to make my own libraries for all languages that I want to offer end-to-end encryption for.

Do C (or something where the mapping to C is known), and lots of languages have FFI libs where wrapping that is fairly trivial, reducing the need to make your own libraries for all languages.

Or do a tool with a CLI, and other langs can call that.

Ideally, your primary implementation does both of those, making it easy to wrap and call. That's how things like GPG are so widely supported.

> Do C (or something where the mapping to C is known), and lots of languages have FFI libs where wrapping that is fairly trivial

That is an interesting idea, yet still a lot of work, sadly. I was hoping somebody had done the legwork already. I looked at Tink [1] and age [2] based on my co-worker's recommendation, but they all seem to have limited implementations in other languages.

[1] https://github.com/google/tink

[2] https://github.com/FiloSottile/age

This is very much what age is designed for.

The Go implementation supports every OS. The Rust implementation (rage) also does, and can be called from C, JavaScript, Python, and anything else with a C FFI. Also, age can be implemented entirely on top of libsodium, so anything with libsodium bindings can easily get an age implementation. I’m working to a TypeScript implementation to demonstrate it.

I’d be interested to hear what language support is missing, to know where to invest in the future.

Heyy! Thank you very much for designing age. It's fantastic. And thank you for making it open source and your continued work!

I wasn't aware that there is widespread support in other languages. I'll have to look into it. The ideal state IMHO would be age support in the standard library of most popular languages, or at least as ubiquitous support as for instance OpenSSL.

My concrete suggestions to make age as ubiquitous as OpenPGP and OpenSSL, would be:

- Better documentation: The age GitHub page and the man page are geared towards the CLI tool, and not the use as a library. There are no examples for other languages and not even a link to rage or the FFI examples you mentioned. Maybe make a website or a mkdocs documentation showing examples, something like this [1] (disclaimer: this is mine)

- Officially supported libraries in other languages: This one is tough, because it's hard work. But maybe if you create a CONTRIBUTING.md document and ask for people to step forward, they will. List out the languages you want to support and specifically call out that you're looking for help.

Once again, thanks for creating age. Much appreciated!!

[1] https://ntfy.sh/docs/publish/

Edit: I could not find instructions on how to use age/rage with Python or JS. Can you point me to them?

It doesn't quite fit your description, but I've been using the following single-file shell script called cryptr.

> A simple shell utility for encrypting and decrypting files using OpenSSL.

https://github.com/nodesocket/cryptr