0.1.1 |
|
---|---|
0.1.0 |
|
#31 in #nonce
25KB
136 lines
recordbox
Welcome to recordbox
🎉
This crate offers a simple API to encrypt id:payload
-style records like network packets or files etc.
Why?
Records are pretty common and often consist of two main elements:
- An ID which identifies/addresses the record; e.g. a filename or a sequence number (even if implicit) or an entry UUID etc.
- The associated payload
This crate offers an easy and uniform API to encrypt a record payload and tie the resulting ciphertext to the record ID, so that you don't have to implement the same basics by yourself everytime.
Encryption
There are three different kinds of boxes; which one is the best depends on your usecase:
Recordbox
The most versatile format is the Recordbox
. It works by using a SIV implementation which uses the ID as associated
data and a fixed nonce.
Advantages:
- Resilient: Due to the nature of SIV constructions, it is completely fine to reuse a record ID for different record payloads. This is useful if the record IDs are not unique (e.g. filenames), and it provides an additional security boundary if your implementation cannot guarantee that a record ID will never be reused.
- Versatile: You can basically use any kind of record ID and payload with this box.
- Deterministic: Because the same ID+plaintext-combination will always result in the same ciphertext, it is easy to implement a fast reverse lookup and subsequently stuff like deduplication etc,
Disadvantages:
- Not randomized: Because the implementation uses a fixed nonce, the same ID+plaintext-combination will always result in the same ciphertext. This may leak information about equal records and in certain circumstances can be enough to completely break a protocol.
- Slow: Most if not all current SIV constructions are significantly slower than e.g. AES-GCM. Even though in most cases this is not a problem, it can be a dealbreaker in certain settings.
UniqueRecordbox
The UniqueRecordbox
is a randomized record box which uses the record ID as (indirect) nonce. It works by deriving a
record-specific subkey from the provided key and the record ID and a deterministic or fixed nonce. This is similar to
the XChaCha-construction and allows the use of arbitrarily long record IDs (as long as they are unique for each record
payload).
Advantages:
- Versatile: You can basically use any kind of record ID and payload with this box.
- Fast (for large records): Because this box allows the use of simple AEAD constructions, the encryption of large record payloads is usually significantly faster than if using a SIV construction.
Disadvantages:
- Fragile: Because the key is derived directly from the record ID, you MUST NEVER reuse a record ID for a different record payload. This has proven to be pretty difficult in certain circumstances; especially if you cannot implement a reliable monotonic counter or create sufficiently large random record IDs.
- Slow (for small records): Because this box uses a rather expensive subkey derivation, it might not be the best choice if you need to work with a lot of small record payloads.
Note:
This is a fallback scheme because as of today, SIV implementations are not easily available in every language. However
in most circumstances you should probably either use a Recordbox
if you can afford a few more CPU cycles or a
FastRecordBox
if performance is critical.
FastRecordBox
The FastRecordBox
is a randomized record box which directly maps the record ID into a nonce (i.e. without deriving a
record-specific subkey).
Advantages:
- Fast: Because this box does not perform any expensive subkey derivation and allows the use of simple AEAD constructions, this is the fastest box scheme available.
- Quite Common: Under the hood, this scheme usually translates to a direct invocation of the AEAD construction, which makes it easy to implement it yourself if necessary.
Disadvantages:
- Fragile: Because the nonce is created directly from the record ID, you MUST NEVER reuse a record ID for a different record payload. This has proven to be pretty difficult in certain circumstances; especially if you cannot implement a reliable monotonic counter.
- Short record IDs only: Usually nonces are pretty short (8 to 12 bytes). Therefore, to avoid collisions, there MUST
be an injective mapping from each
Self
to the nonce. This also means that your record IDs usually cannot be larger than 8 to 12 bytes.
TODO
- Provide implementations for the
RecordBox
- Provide implementations for the
UniqueRecordBox
- Provide implementations for the
FastRecordBox
Dependencies
~2.4–3.5MB
~72K SLoC