Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How-To Crypto #249

Stebalien opened this issue Jun 23, 2017 · 1 comment


Copy link

commented Jun 23, 2017

How-To Crypto

This issue is intended for discussing and formulating rules about how to correctly and securely use crypto. If you notice any suboptimal, insecure, or incorrect use of crypto:

  1. Fix it.
  2. Document the correct way to do it here so that we avoid that mistake in the future.

Rules of Thumb for Signatures


  1. Put everything into the signature.
  2. Always include field separators. Otherwise, sign([][]bytes{"first", "second"}) == sign([][]bytes{"firstsecond", ""}).
  3. If possible, name fields; this helps with forwards compatibility as fields are removed/added. The alternative is to use separators and never remove fields (just blank out non-included ones).
  4. Put in some form of scheme-specific ID (e.g., a protocol ID). Otherwise, an attacker can steal a signature from one protocol and use it elsewhere. Basically, the signed data should describe in what context the signature is valid.

Golden Rules

Without the random oracle assumption (hashes):

You should be able to reconstruct your data-structure (type included) from the signed data.

With the random oracle assumption:

Given a random oracle (a cryptographic hashing algorithm) and a way to invert hashes (go from a hash back to the hashed data), you should be able to reconstruct your data-structure (type included) from the signed data.

Basically, if you can't parse the data you shove into the signing algorithm back into the datastructure you're trying to sign, you're probably doing something wrong.

Encryption Versus Authentication

  • Encryption hides content.
  • Authentication authenticates content.

Not all crypto is authenticated.

As a matter of fact, most (all?) stream ciphers are not authenticated by default because adding a MAC (message authentication code) per block (often 256bits or 32 bytes) is a lot of overhead, you generally want one per packet, not one per block.

How-To Authenticated Crypto

Encrypt then MAC. That is, encrypt the data, then MAC it. There's a really nice StackExchange answer explaining why.

One thing you need to remember is what's being authenticated. In this case, you're authenticating the ciphertext. That means that the ciphertext is was "signed" (MACed) by a party knowing the shared key. However, this does not mean that the ciphertext is, e.g., the next ciphertext in the stream, or that you haven't already seen the cipher text, or even that the cipher text came from this particular stream.


This comment has been minimized.

Copy link

commented Oct 26, 2017

Added "Encryption Versus Authentication" section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
1 participant
You can’t perform that action at this time.