https://github.com/ferd/hairnet
An Erlang library wrapping AES-GCM (AEAD) crypto in a Fernet-like interface
https://github.com/ferd/hairnet
Last synced: about 1 month ago
JSON representation
An Erlang library wrapping AES-GCM (AEAD) crypto in a Fernet-like interface
- Host: GitHub
- URL: https://github.com/ferd/hairnet
- Owner: ferd
- License: other
- Created: 2016-04-26T17:58:05.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2021-01-22T20:50:22.000Z (over 4 years ago)
- Last Synced: 2024-03-14T17:32:23.620Z (about 1 year ago)
- Language: Erlang
- Size: 12.7 KB
- Stars: 29
- Watchers: 3
- Forks: 6
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
hairnet
=====A take on [fernet](https://github.com/fernet/fernet-erl) using AES-GCM
([AEAD](https://en.wikipedia.org/wiki/Authenticated_encryption))
rather than fernet's AES-128 in CBC mode + HMAC.The idea is to take what is now a fairly weak crypto library and bring
it up to a higher standard while maintaining a similar interface.The objective is to:
> "takes a user-provided message (an arbitrary sequence of
> bytes), a key (256 bits), and the current time, and produces a token, which
> contains the message in a form that can't be read or altered without the key."In terms of AEAD, the PlainText will be the user-provided message, the key
should be any Erlang binary (please use a different one from the one in
`fernet` if you are upgrading), and the current time is going to be used as
the additional authenticated data (AAD), which can be used by the party
doing decryption to validate for staleness.## Interface
```erlang
1> Key = hairnet:generate_encoded_key().
<<"BVt1_R20scbTwz9t05PrtE4EFAauMeRKTxbwYmUiafY=">>
2> Token = hairnet:generate_token("hello", Key).
<<"AQAAAABXH4wKw8DqUtDjJxAX3BuEHGP9xke0tfY-73uzVCpa1iT5f1wgAAAABbhBUeFl">>
3> hairnet:verify_and_decrypt_token(Token, Key, infinity).
{ok, <<"hello">>}
4> TTL = 10. % 10 Seconds
10
5> hairnet:verify_and_decrypt_token(Token, Key, TTL).
{error, too_old}
```### Difference from fernet
- `encode_key/2` is gone, since there is no longer a distinction between
a signing and an encryption key; the AES-GCM algorithm handles this.
- The format changed since the data size is more variable given the AAD,
and prefixed lengths are being used to carry the content.
- pkcs7 is no longer needed, and the padding-related errors are no longer
returnable, since this is all handled by the crypto library.
- block sizes warnings are gone, instead an overall `payload_format`
error value can be returned.
- Dropped compatibility for pre-18 Erlang/OTP copiesBuild
-----$ rebar3 compile
Test
----$ rebar3 do eunit, dialyzer
Warnings
--------The [publications from NIST on the
algorithm](http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf)
have the following specifications:> The following requirement applies to all implementations that use either 1) the
> deterministic construction with IVs whose length is not 96, or 2) the RBG-based
> construction, for IVs of any length. In other words, unless an implementation
> only uses 96-bit IVs that are generated by the deterministic construction:
>
> **The total number of invocations of the authenticated encryption function shall
> not exceed 2^32, including all IV lengths and all instances of the
> authenticated encryption function with the given key.**
>
> This is a “global” requirement that can be achieved by appropriate “local”
> limits on each instance of the authenticated encryption function with a given
> key. For example, suppose an implementation consists of 2^10 devices that only
> support 64-bit, 96-bit, and 128-bit IVs. One way to satisfy the above
> requirement would be to limit each device to 2^20 invocations with 64-bit IVs,
> 2^21 invocations with 96-bit IVs, and 2^20 invocations with 128-bit IVs.This implementation uses Erlang's `crypto:strong_rand_bytes(16)` to generate
128-bit IVs.As such, it would be recommended to rotate the key used to encrypt content once
such limits (2^21 calls locally, or 2^32 overall) are reached to avoid
weakening the security of the private key.