Documentation ¶
Overview ¶
Package dvx provides an easy-to-use interface to a Cryptography service, that uses state-of-the-art primitives. It provides 4 main categories of supported operations: Encryption/Decryption, Signing/Verifying, MAC, and as a special higher-order algorithm: TOTP Creation/Verification.
Goals ¶
1. No storage needed
dvx doesn't need any storage, as it derives all internal keys from a root secret. This root secret can live inside a hardware-security-module (HSM via PKCS#11) or as an alternative be held in a protected RAM section.
2. Hard to misuse
dvx has an easy-to-use interface and clear separation (boundaries) of liabilities.
Index ¶
- Constants
- func DecodeExpect(s string, expected TypePrefix) (version string, data []byte, err error)
- func Encode(typePrefix TypePrefix, data []byte) string
- type DV1
- func (d DV1) Decrypt(key []byte, cipher []byte) (data []byte, err error)
- func (d DV1) Encrypt(key []byte, data []byte) (cipher []byte, err error)
- func (d DV1) KDF512(password []byte, salt []byte) (key []byte, err error)
- func (d DV1) MAC256(key []byte, message []byte) (tag []byte, err error)
- func (d DV1) MAC512(key []byte, message []byte) (tag []byte, err error)
- func (d DV1) Sign(privateKey []byte, message []byte) (signature []byte, err error)
- func (d DV1) Verify(publicKey []byte, message []byte, signature []byte) (valid bool, err error)
- type KeyPool
- type Primitive
- type Protocol
- func (p *Protocol) CreateSignKey(keyRing string) (publicKey []byte, err error)
- func (p *Protocol) Decrypt(keyRing string, ciphertext string) (data []byte, err error)
- func (p *Protocol) Encrypt(keyRing string, data []byte) (ciphertext string, err error)
- func (p *Protocol) GenerateTOTP(keyRing string, issuer string, accountName string, accountID string) (id string, uri string, err error)
- func (p *Protocol) MAC(keyRing string, message []byte) (tag string, err error)
- func (p *Protocol) Sign(keyRing string, message []byte) (signature string, rawSignature []byte, err error)
- func (p *Protocol) Verify(keyRing string, message []byte, signature string) (valid bool, err error)
- func (p *Protocol) VerifyPK(publicKey []byte, message []byte, signature string) (valid bool, err error)
- func (p *Protocol) VerifyTOTP(keyRing string, id string, accountID string, code string) (valid bool, err error)
- type TypePrefix
Constants ¶
const ( // Version is the version header of the current Protocol implementation. It // is the lower-cased string name of the underlying Primitive. Version string = "dv1" )
Variables ¶
This section is empty.
Functions ¶
func DecodeExpect ¶
func DecodeExpect(s string, expected TypePrefix) (version string, data []byte, err error)
DecodeExpect is like Decode, but additionally verifies that the decoded TypePrefix matches the expected TypePrefix. If they match the TypePrefix is removed from the result, otherwise an error is returned.
func Encode ¶
func Encode(typePrefix TypePrefix, data []byte) string
Encode encodes a TypePrefix and associated data according to the current major DVX version (DV1)
Types ¶
type KeyPool ¶
type KeyPool interface { // KDF32 is a key derivation function that returns a 32-byte key for the // keyRing passed to it. Equal keyRings must always result in equal keys. KDF32(keyRing []byte) (key []byte, err error) // KDF64 is a key derivation function that returns a 64-byte key for the // keyRing passed to it. Equal keyRings must always result in equal keys. KDF64(keyRing []byte) (key []byte, err error) // Close closes the KeyPool and it's underlying instances. Close() error }
KeyPool is an interface for a key derivation loader.
func WrapDVXAsKeyPool ¶
WrapDVXAsKeyPool provides a KeyPool implementation by using the Primitive.MAC256 and Primitive.MAC512 functions as key-derivation-functions. The passed rootKey is used as key for the MAC-constructions. A passed keyRing is used a message during derivation.
type Primitive ¶
type Primitive interface { KDF512(password []byte, salt []byte) (key []byte, err error) MAC256(key []byte, message []byte) (tag []byte, err error) MAC512(key []byte, message []byte) (tag []byte, err error) Encrypt(key []byte, data []byte) (cipher []byte, err error) Decrypt(key []byte, cipher []byte) (data []byte, err error) Sign(privateKey []byte, message []byte) (signature []byte, err error) Verify(publicKey []byte, message []byte, signature []byte) (valid bool, err error) }
Primitive is a low level cryptographic contract.
type Protocol ¶
type Protocol struct {
// contains filtered or unexported fields
}
Protocol is an implementation of the current major dvx version. It can decrypt and verify ciphers, signatures and tags from all previous major versions.
This means the Protocol implementation under azoo.dev/utils/dvx will always use DV1 as it's Primitive. When DV2 will eventually get released, it will be hosted under azoo.dev/utils/dvx/v2, and it's Protocol will use DV2 as it's Primitive, but will be able to decrypt and verify DV1 content.
The interface of Protocol is closely tied to that of Dragon (originally it's parent project), but may be used directly in non-Dragon scenarios or to locally verify signatures (VerifyPK) without the need to contact a Dragon server.
func NewProtocol ¶
NewProtocol creates a new Protocol from a map of KeyPool. The map specifies different KeyPool for major DVX versions.
Therefore, a valid map would be:
map[string]dvx.KeyPool{ dvx.Version: dvx.WrapDVXAsKeyPool(dvx.DV1{}, []byte{}), }
func (*Protocol) CreateSignKey ¶
CreateSignKey derives a private key using the keyRing and returns its public key counterpart to the caller. It can be used in conjunction with VerifyPK to verify signatures created with Sign using the same keyRing.
func (*Protocol) Decrypt ¶
Decrypt derives a secret key `sk` using the keyRing and subsequently decrypts ciphertext using `sk`.
func (*Protocol) Encrypt ¶
Encrypt derives a secret key `sk` using the keyRing and subsequently encrypts data using `sk`.
func (*Protocol) GenerateTOTP ¶
func (p *Protocol) GenerateTOTP(keyRing string, issuer string, accountName string, accountID string) (id string, uri string, err error)
GenerateTOTP derives a secret key `sk` using the keyRing. Afterwards, it generates 32 random bytes `raw-id`, which are encoded to a totp-id using Encode with a TOTP TypePrefix. Subsequently, `sk` and `raw-id` are used to derive an intermediate key `i`, which is mixed with an `accountID` to cryptographically bind the final totp-secret-key `totp-sk` to a specific end-user account.
The `totp-sk` secret used for totp calculations has 32 bytes and SHA256 is selected as a totp algorithm. Moreover, digits and period are left to their defaults: 6 and 30 respectively.
The returned `id` must be stored by the caller in order to VerifyTOTP codes in the future. NO additional integrity checks/measurements are needed in storage to protect from id-swapping attacks, as `account-id` is cryptographically bound and `totp-sk` depends on it. Although the returned `id` is useless in itself, it should not be returned to the end-user client.
The returned uri is a Google Authenticator compliant URI string (https://github.com/google/google-authenticator/wiki/Key-Uri-Format) that can be used by end-users to set up an authenticator. It can be directly passed to azoo.dev/utils/qr generator to create a QR-image of the uri for easy end-user set up.
func (*Protocol) MAC ¶
MAC derives a secret key `sk` using the keyRing and subsequently calculates a MAC tag of data using `sk`.
func (*Protocol) Sign ¶
func (p *Protocol) Sign(keyRing string, message []byte) (signature string, rawSignature []byte, err error)
Sign derives a private key using the keyRing and subsequently calculates a signature for data.
func (*Protocol) Verify ¶
Verify derives a private key using the keyRing and subsequently uses its public key counterpart to verify the signature for data.
func (*Protocol) VerifyPK ¶
func (p *Protocol) VerifyPK(publicKey []byte, message []byte, signature string) (valid bool, err error)
VerifyPK uses the provided public key directly to verify the signature for data. VerifyPK doesn't derive any key from the internal KeyPool and is safe to use for Protocol objects with empty KeyPool maps. It can be used verify a DVX signature string without access to the KeyPool and respectively private key counterparts.
func (*Protocol) VerifyTOTP ¶
func (p *Protocol) VerifyTOTP(keyRing string, id string, accountID string, code string) (valid bool, err error)
VerifyTOTP derives a totp-secret-key `totp-sk` using the same procedure as described in GenerateTOTP and subsequently uses it to verify the provided code in constant-time.
type TypePrefix ¶
type TypePrefix string
TypePrefix is a string defining the prefix of the encoded dvx string
const ( // Encrypted is the TypePrefix for encrypted content Encrypted TypePrefix = "enc" // Signed is the TypePrefix for a signature Signed TypePrefix = "sig" // Tagged is the TypePrefix for a MAC Tagged TypePrefix = "tag" // TOTP is the TypePrefix for a TOTP selector id TOTP TypePrefix = "totp" )