README
¶
Skykey Manager
The skykey
package defines Skykeys used for encrypting files in Skynet and
provides a way to persist Skykeys using a SkykeyManager
that manages these
keys in a file on-disk.
The file consists of a header which is:
SkykeyFileMagic | SkykeyVersion | Length
The SkykeyFileMagic
never changes. The version only changes when
backwards-incompatible changes are made to the design of Skykeys
or to the way
this file is structured. The length refers to the number of bytes in the file.
When adding a Skykey
to the file, a Skykey
is unmarshaled and appended to
the end of the file and the file is then synced. Then the length field in the
header is updated to indicate the newly written bytes and the file is synced
once again.
Skykeys
A Skykey
is a key associated with a name to be used in Skynet to share
encrypted files. Each key has a name and a unique identifier.
Usage
Skykeys are primarily used for encrypting skyfiles. Currently all skykeys are used with the
XChaCha20 stream cipher. Key re-use is safe with this encryption scheme if we
use random nonces for each message. This is safe until 2 << 96
messages are
transmitted.
Key Derivation
The skykey manager stores only master skykeys. These skykeys are not used directly for encryption/decryption. Rather they are used to derive file-specific Skykeys. File-specific skykeys share the same key material as the master skykey they are derived from. They differ in the nonce value. This allows us to reuse the master skykey for multiple files, by using a new file-specific skykey for every new file.
The method GenerateFileSpecificSubkey
is used to create new file-specific
sub-keys from a master skykey.
Further levels of key derivation may be necessary and are supported by using the
DeriveSubkey
method.
Skyfile encryption
Two other types of subkeys are the ones actually used for encrypting skyfiles.
There is a BaseSector
derivation and a Fanout
derivation which are used for
encrypting the base sector and fanout of a skyfile respectively.
This is necessary because of the final level of key derivation used in the upload
process of Sia. When splitting up files for redundancy, each (chunkIndex, pieceIndex)
upload uses a different XChaCha20 nonce as well. To avoid re-using
the same (chunkIndex, pieceIndex)
derivation for the base sector and fanout
sections, we just use a different nonce for each.
Documentation
¶
Index ¶
- Constants
- Variables
- type Skykey
- func (sk *Skykey) CipherKey() (crypto.CipherKey, error)
- func (sk *Skykey) DeriveSubkey(derivation []byte) (Skykey, error)
- func (sk *Skykey) FromString(s string) error
- func (sk *Skykey) GenerateFileSpecificSubkey() (Skykey, error)
- func (sk Skykey) ID() (keyID SkykeyID)
- func (sk *Skykey) Nonce() []byte
- func (sk *Skykey) SubkeyWithNonce(nonce []byte) (Skykey, error)
- func (sk Skykey) ToString() (string, error)
- type SkykeyID
- type SkykeyManager
- func (sm *SkykeyManager) AddKey(sk Skykey) error
- func (sm *SkykeyManager) CreateKey(name string, cipherType crypto.CipherType) (Skykey, error)
- func (sm *SkykeyManager) IDByName(name string) (SkykeyID, error)
- func (sm *SkykeyManager) KeyByID(id SkykeyID) (Skykey, error)
- func (sm *SkykeyManager) KeyByName(name string) (Skykey, error)
- func (sm *SkykeyManager) SupportsCipherType(ct crypto.CipherType) bool
Constants ¶
const ( // SkykeyIDLen is the length of a SkykeyID SkykeyIDLen = 16 // MaxKeyNameLen is the maximum length of a skykey's name. MaxKeyNameLen = 128 )
Variables ¶
var ( // SkykeySpecifier is used as a prefix when hashing Skykeys to compute their // ID. SkykeySpecifier = types.NewSpecifier("Skykey") // SkykeyFileMagic is the first piece of data found in a Skykey file. SkykeyFileMagic = types.NewSpecifier("SkykeyFile") // ErrSkykeyWithNameAlreadyExists indicates that a key cannot be created or added // because a key with the same name is already being stored. ErrSkykeyWithNameAlreadyExists = errors.New("Skykey name already used by another key.") // ErrSkykeyWithIDAlreadyExists indicates that a key cannot be created or // added because a key with the same ID (and therefore same key entropy) is // already being stored. ErrSkykeyWithIDAlreadyExists = errors.New("Skykey ID already exists.") // SkykeyPersistFilename is the name of the skykey persistence file. SkykeyPersistFilename = "skykeys.dat" )
Functions ¶
This section is empty.
Types ¶
type Skykey ¶
type Skykey struct { Name string CipherType crypto.CipherType Entropy []byte }
Skykey is a key used to encrypt/decrypt skyfiles.
func (*Skykey) CipherKey ¶ added in v1.4.8
CipherKey returns the crypto.CipherKey equivalent of this Skykey.
func (*Skykey) DeriveSubkey ¶ added in v1.4.8
DeriveSubkey is used to create Skykeys with the same key, but with a different nonce. This is used to create file-specific keys, and separate keys for Skyfile baseSector uploads and fanout uploads.
func (*Skykey) FromString ¶ added in v1.4.8
FromString decodes the base64 string into a Skykey.
func (*Skykey) GenerateFileSpecificSubkey ¶ added in v1.4.8
GenerateFileSpecificSubkey creates a new subkey specific to a certain file being uploaded/downloaded. Skykeys can only be used once with a given nonce, so this method is used to generate keys with new nonces when a new file is uploaded.
func (Skykey) ID ¶
ID returns the ID for the Skykey. A master Skykey and all file-specific skykeys derived from it share the same ID because they only differ in nonce values, not key values. This fact is used to identify the master Skykey with which a Skyfile was encrypted.
func (*Skykey) SubkeyWithNonce ¶ added in v1.4.8
SubkeyWithNonce creates a new subkey with the same key data as this key, but with the given nonce.
type SkykeyID ¶
type SkykeyID [SkykeyIDLen]byte
SkykeyID is the identifier of a skykey.
func (*SkykeyID) FromString ¶ added in v1.4.8
FromString decodes the base64 string into a Skykey ID.
type SkykeyManager ¶
type SkykeyManager struct {
// contains filtered or unexported fields
}
SkykeyManager manages the creation and handling of new skykeys which can be referenced by their unique name or identifier.
func NewSkykeyManager ¶
func NewSkykeyManager(persistDir string) (*SkykeyManager, error)
NewSkykeyManager creates a SkykeyManager for managing skykeys.
func (*SkykeyManager) AddKey ¶
func (sm *SkykeyManager) AddKey(sk Skykey) error
AddKey creates a key with the given name, cipherType, and entropy and adds it to the key file.
func (*SkykeyManager) CreateKey ¶
func (sm *SkykeyManager) CreateKey(name string, cipherType crypto.CipherType) (Skykey, error)
CreateKey creates a new Skykey under the given name and cipherType.
func (*SkykeyManager) IDByName ¶
func (sm *SkykeyManager) IDByName(name string) (SkykeyID, error)
IDByName returns the ID associated with the given key name.
func (*SkykeyManager) KeyByID ¶
func (sm *SkykeyManager) KeyByID(id SkykeyID) (Skykey, error)
KeyByID returns the Skykey associated with that ID.
func (*SkykeyManager) KeyByName ¶
func (sm *SkykeyManager) KeyByName(name string) (Skykey, error)
KeyByName returns the Skykey associated with that key name.
func (*SkykeyManager) SupportsCipherType ¶
func (sm *SkykeyManager) SupportsCipherType(ct crypto.CipherType) bool
SupportsCipherType returns true if and only if the SkykeyManager supports keys with the given cipher type.