1. 57
  1.  

  2. 6

    I like the simplicity of this tool and that it’s almost all written in a reasonably safe language.

    If I were evaluating it as an alternative to e.g. PGP I would want to know the following:

    1. What crypto does it use now?
    2. What’s the upgrade path and backwards-compatibility story?
    3. How much plaintext metadata is paired with the encrypted blob? (in particular, what info do I leak about who I’m communicating with and who I am if an encrypted file is acquired by an adversary)
    1. 4
      1. ChaCha20Poly1305 in STREAM, X25519 for E-S ECDH, HKDF with SHA-256. Boring and modern.
      2. Recipient types can be added with backwards compatibility, everything else rests on the one joint of the major version.
      3. Very good question: none. Recipients have to do trial decryptions with the private key to figure out if they are the recipient. (SSH key recipients have a 32 bit key tag because the private key might be password protected.)
      1. 1

        Thanks. How is the key tag derived from the public ssh key?

        Regarding backwards compat, will there be a guarantee that future age binaries will be able to decrypt ciphertext from earlier major versions? I guess this doesn’t matter much given how easy it is to distribute statically linked go programs.

        1. 2

          It’s a truncated hash of the serialised public key.

          We haven’t committed to a policy yet, but yes I think we’ll support decryption forever.

    2. 6

      This looks great, let’s please replace PGP with it everywhere. :D

      1. 9

        Yes, let’s replace a system which has been tested and proven and worked on since the 1990s with a random 47-commit project someone just tossed up on GitHub. Because good encryption is easy.

        /s

        1. 10

          File encryption is in fact kind of easy, thanks to everything we learned in the last 30 years.

          1. 10

            Yes, actually.

            1. 4

              I don’t see the point in sarcasm. PGP does many things and most of them are handled poorly be default. This is not a PGP replacement, it’s a tools with single purpose: file encryption. It’s not for safe transfers, it’s not for mail. It’s got a mature spec and it’s designed and developed by folks who are in the crypto community and there are two ref implementations. It does one thing and does it well which is everything PGP isn’t.

              1. 3

                I guess even the author of PGP would be up for that: https://www.vice.com/en_us/article/vvbw9a/even-the-inventor-of-pgp-doesnt-use-pgp

                1. 3

                  In a cryptography context, “since the 1990s” is basically derogatory. Old crypto projects are infamous for keeping awful insecure garbage around for compatibility, and this has been abused many many times (downgrading TLS to “export grade” primitives anyone?)

                  1. 1

                    I think icefox’s comment was already being sarcastic

                    1. 6

                      Not necessarily, PGP is a trashfire

                      1. 2

                        Why do you say that?

                        1. 7

                          This should answer your question better than I ever will.

                          https://latacora.micro.blog/2019/07/16/the-pgp-problem.html

                          1. 1

                            Thanks

                2. 3

                  Shouldn’t nonce contain unique value? I am no Go expert but it seems that it will always be null string.

                  1. 1

                    That is indeed being passed zero bytes. I think this is only dangerous if you reuse the same nonce for different messages with the same key. It’s a bit subtle, but all the usages of that function I can find are given a unique key every time (like the scrypt recipient has a unique salt, and the x25519 recipient uses emphemeral keys).

                    The document at https://age-encryption.org/v1 contains some language about making sure that property is true (e.g. A new salt MUST be generated for every new file key.)

                    1. 10

                      Indeed, this is intentional and safe, but worth a comment in the code. Coming up, thank you.

                      1. 4

                        Is there a reason not to randomize the nonce? This seems like a “we could use a static nonce, but a random nonce costs us nothing and it may save us if other things go wrong” situation.

                        1. 3

                          IMO better to not randomize the nonce and leave a comment explicitly stating why. While I appreciate “defensive engineering” I think code that that has no rational justification rots a codebase over the long term. E.g. anything that eventually results in comments like “XXX: not sure why this needed” makes it really hard to modify the code.

                          1. 2

                            Not really, it’s just superfluous overhead. It wouldn’t be unreasonable to randomise it, but I’m fairly confident in the randomness of the key here.

                    2. 1

                      I know I am using signing keys for encryption, which is unholy. I’m sorry? It would be nice to check further for cross-protocol attacks but it looks like we’ll be ok.