Crates.io | fog-crypto |
lib.rs | fog-crypto |
version | 0.5.3 |
source | src |
created_at | 2021-01-21 02:13:04.2243 |
updated_at | 2023-08-27 03:33:02.19804 |
description | Utilities to make signing & encryption easier for small, independent blocks of bytes. Primary use-case is the fog-pack crate. |
homepage | |
repository | https://github.com/Cognoscan/fog-crypto |
max_upload_size | |
id | 344709 |
size | 393,018 |
A simple storage-oriented cryptographic library that offers you freedom from choice. It supports hashing, public key signatures, public key & symmetric key encryption, key export/import, and basic key storage.
Getting cryptography right can be hard. This library attempts to make things easy by only providing a small number of cryptographic primitives, makes strong decisions about the cryptographic algorithms and their implementations, and tries to limit the number of bad things an end user can do. Changing algorithms should be infrequent, and follows a planned process (see Cryptographic Versioning). On the plus side, it's pretty hard to misuse this library in ways that leak secrets and compromise security. On the downside, this library is pretty strongly meant for working with stored data, not communication protocols, and cannot support even remotely unusual cryptographic operations. Forcing use of a single preferred set of algorithms also greatly limits hardware compatibility.
You probably shouldn't be using this library directly. Portions of it should instead be
exported by an implementor of a Vault, and you should use those. Alternately, you might be
using this through fog-pack
, which also re-exports
portions of this library. You can expect to see these primitives:
General:
Vault
: A structure that can hold onto your cryptographic keys.Hashing:
Hash
: The cryptographic hash of a sequence of bytes.HashState
: A structure for iteratively feeding in bytes to create a Hash
.Signatures:
Signature
: A validated cryptographic signature of a Hash
.UnverifiedSignature
: A cryptographic signature that hasn't been verified yet.IdentityKey
: A private key for signing hashes.Identity
: A public key identity to indicate which IdentityKey
created a given Signature
.Symmetric-Key Encryption:
StreamKey
: A shared symmetric key for encrypting & decrypting data.StreamId
: A public, unique identifier for indicating what StreamKey
should be used
for decrypting encrypted data.Public-Key Encryption:
LockKey
: A private key for decrypting data.LockId
: A public key to indicate what LockKey
should be used for decrypting encrypted
data.Encrypted Storage:
IdentityLockbox
: An encrypted container that holds a IdentityKey
.StreamLockbox
: An encrypted container that holds a StreamKey
.LockLockbox
: An encrypted container that holds a LockKey
.DataLockbox
: An encrypted container that holds a byte sequence.First, re-export the structs listed in the user guidelines. If your vault is entirely in
software, you probably want to use the various ContainedXXX
structs for holding keys, and
store them by exporting them for some master key. Avoid letting the keys sit around in some
unencrypted form. Your master key can be created by obtaining a 32-byte random byte sequence,
prepending it with a 1 (the version byte), and using ContainedStreamKey
's try_from
implementation to encapsulate the sequence. Make sure to zeroize the master key after doing
this!
If your vault has a hardware or OS component, your hardware vault's capabilities may be limited in its ability to store all types of keys. In this case, you will need to have a software-side implementation to make up for the missing storage. A recommended approach here is to actually accept a reference to a pure-software vault on creation, and let it handle any unsupported operations. Your vault can then capture all operations that it does support.
Alternately, if your hardware / OS component supports an extremely small subset of
functionality, cannot perform any type of key import/export, and is meant for high risk
scenarios, consider not supporting the Vault trait at all. Instead, create your own key store
interface, and provide backer implementations for just the supported interfaces (your options
being SignInterface
, StreamInterface
, and LockInterface
).
The currently used algorithms are:
This library has 4 core cryptographic algorithms that may be upgraded over time:
Upgrades should be infrequent, and are done roughly when an existing recommended algorithm is regarded as weak but not yet broken.
The ideal upgrade process is:
This is the best-case upgrade scenario. If an existing algorithm is considered broken, the DEFAULT_VERSION and MIN_VERSION will be incremented as soon as possible. "Broken" here means it is feasible for a well-funded attacker to compromise the algorithm. Breaking compatibility with deployed code is considered an acceptable choice when security is compromised.
We are almost certainly going to upgrade the signing and DH exchange algorithms in the future, as we will need to move to post-quantum algorithms. There's no similar looming threat for the hash & symmetric encryption algorithms.