Documentation ¶
Index ¶
- Constants
- Variables
- func CalcEncompassingBlocks(offset, length int64, blockSize int) (firstBlock, blockCount int64)
- func CalcEncryptedSize(dataSize int64, scheme storj.EncryptionScheme) (int64, error)
- func Decrypt(cipherData []byte, cipher storj.Cipher, key *storj.Key, nonce *storj.Nonce) (data []byte, err error)
- func DecryptAESGCM(cipherData []byte, key *storj.Key, nonce *AESGCMNonce) (data []byte, err error)
- func DecryptKey(keyToDecrypt storj.EncryptedPrivateKey, cipher storj.Cipher, key *storj.Key, ...) (*storj.Key, error)
- func DecryptPath(path storj.Path, cipher storj.Cipher, key *storj.Key) (decrypted storj.Path, err error)
- func DecryptPathRaw(raw string, cipher storj.Cipher, key *storj.Key) (string, error)
- func DecryptSecretBox(cipherData []byte, key *storj.Key, nonce *storj.Nonce) (data []byte, err error)
- func DeriveContentKey(path storj.Path, key *storj.Key) (derivedKey *storj.Key, err error)
- func DeriveDefaultPassword(password, salt []byte) ([]byte, error)
- func DeriveKey(key *storj.Key, message string) (*storj.Key, error)
- func DerivePathKey(path storj.Path, key *storj.Key, depth int) (derivedKey *storj.Key, err error)
- func DeriveRootKey(password, salt []byte, path storj.Path) (*storj.Key, error)
- func Encrypt(data []byte, cipher storj.Cipher, key *storj.Key, nonce *storj.Nonce) (cipherData []byte, err error)
- func EncryptAESGCM(data []byte, key *storj.Key, nonce *AESGCMNonce) (cipherData []byte, err error)
- func EncryptKey(keyToEncrypt *storj.Key, cipher storj.Cipher, key *storj.Key, ...) (storj.EncryptedPrivateKey, error)
- func EncryptPath(path storj.Path, cipher storj.Cipher, key *storj.Key) (encrypted storj.Path, err error)
- func EncryptPathRaw(raw string, cipher storj.Cipher, key *storj.Key) (string, error)
- func EncryptSecretBox(data []byte, key *storj.Key, nonce *storj.Nonce) (cipherData []byte, err error)
- func Increment(nonce *storj.Nonce, amount int64) (truncated bool, err error)
- func StoreDecryptPath(bucket string, path paths.Encrypted, cipher storj.Cipher, store *Store) (unencPath paths.Unencrypted, err error)
- func StoreDeriveContentKey(bucket string, path paths.Unencrypted, store *Store) (key *storj.Key, err error)
- func StoreDerivePathKey(bucket string, path paths.Unencrypted, store *Store) (key *storj.Key, err error)
- func StoreEncryptPath(bucket string, path paths.Unencrypted, cipher storj.Cipher, store *Store) (encPath paths.Encrypted, err error)
- func Transform(rr ranger.Ranger, t Transformer) (ranger.Ranger, error)
- func TransformReader(r io.ReadCloser, t Transformer, startingBlockNum int64) io.ReadCloser
- func TransformReaderSize(r io.ReadCloser, t Transformer, startingBlockNum int64, expectedSize int64) io.ReadCloser
- type AESGCMNonce
- type Base
- type NoopTransformer
- type Store
- func (s *Store) Add(bucket string, unenc paths.Unencrypted, enc paths.Encrypted, key storj.Key) error
- func (s *Store) GetDefaultKey() *storj.Key
- func (s *Store) Iterate(fn func(string, paths.Unencrypted, paths.Encrypted, storj.Key) error) error
- func (s *Store) LookupEncrypted(bucket string, path paths.Encrypted) (revealed map[string]string, consumed paths.Encrypted, base *Base)
- func (s *Store) LookupUnencrypted(bucket string, path paths.Unencrypted) (revealed map[string]string, consumed paths.Unencrypted, base *Base)
- func (s *Store) SetDefaultKey(defaultKey *storj.Key)
- type Transformer
- func NewAESGCMDecrypter(key *storj.Key, startingNonce *AESGCMNonce, encryptedBlockSize int) (Transformer, error)
- func NewAESGCMEncrypter(key *storj.Key, startingNonce *AESGCMNonce, encryptedBlockSize int) (Transformer, error)
- func NewDecrypter(cipher storj.Cipher, key *storj.Key, startingNonce *storj.Nonce, ...) (Transformer, error)
- func NewEncrypter(cipher storj.Cipher, key *storj.Key, startingNonce *storj.Nonce, ...) (Transformer, error)
- func NewSecretboxDecrypter(key *storj.Key, startingNonce *storj.Nonce, encryptedBlockSize int) (Transformer, error)
- func NewSecretboxEncrypter(key *storj.Key, startingNonce *storj.Nonce, encryptedBlockSize int) (Transformer, error)
Examples ¶
Constants ¶
const (
// AESGCMNonceSize is the size of an AES-GCM nonce
AESGCMNonceSize = 12
)
Variables ¶
var ErrDecryptFailed = errs.Class("decryption failed, check encryption key")
ErrDecryptFailed is the errs class when the decryption fails
var ErrInvalidConfig = errs.Class("invalid encryption configuration")
ErrInvalidConfig is the errs class for invalid configuration
var Error = errs.Class("encryption error")
Error is the default encryption errs class
Functions ¶
func CalcEncompassingBlocks ¶
CalcEncompassingBlocks is a useful helper function that, given an offset, length, and blockSize, will tell you which blocks contain the requested offset and length
func CalcEncryptedSize ¶
func CalcEncryptedSize(dataSize int64, scheme storj.EncryptionScheme) (int64, error)
CalcEncryptedSize calculates what would be the size of the cipher data after encrypting data with dataSize using a Transformer with the given encryption scheme.
func Decrypt ¶
func Decrypt(cipherData []byte, cipher storj.Cipher, key *storj.Key, nonce *storj.Nonce) (data []byte, err error)
Decrypt decrypts cipherData with the given cipher, key and nonce
func DecryptAESGCM ¶
DecryptAESGCM decrypts byte data with a key and nonce. The plain data is returned
func DecryptKey ¶
func DecryptKey(keyToDecrypt storj.EncryptedPrivateKey, cipher storj.Cipher, key *storj.Key, nonce *storj.Nonce) (*storj.Key, error)
DecryptKey decrypts keyToDecrypt with the given cipher, key and nonce
func DecryptPath ¶
func DecryptPath(path storj.Path, cipher storj.Cipher, key *storj.Key) (decrypted storj.Path, err error)
DecryptPath decrypts path with the given key
func DecryptPathRaw ¶ added in v0.14.2
DecryptPathRaw decrypts the path using the provided key directly. DecryptPath should be preferred if possible.
func DecryptSecretBox ¶
func DecryptSecretBox(cipherData []byte, key *storj.Key, nonce *storj.Nonce) (data []byte, err error)
DecryptSecretBox decrypts byte data with a key and nonce. The plain data is returned
func DeriveContentKey ¶
DeriveContentKey derives the key for the encrypted object data using the root key. This method must be called on an unencrypted path.
func DeriveDefaultPassword ¶ added in v0.14.0
DeriveDefaultPassword combines a salt from the project with a user password to create a default password used for DeriveRootKey in the case that a single secret should be used to derive all of the bucket level secrets. See the password key derivation design doc.
func DerivePathKey ¶
DerivePathKey derives the key for the given depth from the given root key. This method must be called on an unencrypted path.
func DeriveRootKey ¶ added in v0.14.0
DeriveRootKey derives a root key for some path using the salt for the bucket and a password from the user. See the password key derivation design doc.
func Encrypt ¶
func Encrypt(data []byte, cipher storj.Cipher, key *storj.Key, nonce *storj.Nonce) (cipherData []byte, err error)
Encrypt encrypts data with the given cipher, key and nonce
func EncryptAESGCM ¶
EncryptAESGCM encrypts byte data with a key and nonce. The cipher data is returned
func EncryptKey ¶
func EncryptKey(keyToEncrypt *storj.Key, cipher storj.Cipher, key *storj.Key, nonce *storj.Nonce) (storj.EncryptedPrivateKey, error)
EncryptKey encrypts keyToEncrypt with the given cipher, key and nonce
func EncryptPath ¶
func EncryptPath(path storj.Path, cipher storj.Cipher, key *storj.Key) (encrypted storj.Path, err error)
EncryptPath encrypts path with the given key
Example ¶
package main import ( "encoding/hex" "fmt" "storj.io/storj/pkg/encryption" "storj.io/storj/pkg/storj" ) func main() { var path = "fold1/fold2/fold3/file.txt" // seed seed := new(storj.Key) for i := range seed { seed[i] = byte(i) } fmt.Printf("root key (%d bytes): %s\n", len(seed), hex.EncodeToString(seed[:])) // use the seed for encrypting the path encryptedPath, err := encryption.EncryptPath(path, storj.AESGCM, seed) if err != nil { panic(err) } fmt.Println("path to encrypt:", path) fmt.Println("encrypted path: ", encryptedPath) // decrypting the path decryptedPath, err := encryption.DecryptPath(encryptedPath, storj.AESGCM, seed) if err != nil { panic(err) } fmt.Println("decrypted path: ", decryptedPath) // handling of shared path sharedPath := storj.JoinPaths(storj.SplitPath(encryptedPath)[2:]...) fmt.Println("shared path: ", sharedPath) derivedKey, err := encryption.DerivePathKey(decryptedPath, seed, 2) if err != nil { panic(err) } fmt.Printf("derived key (%d bytes): %s\n", len(derivedKey), hex.EncodeToString(derivedKey[:])) decryptedPath, err = encryption.DecryptPath(sharedPath, storj.AESGCM, derivedKey) if err != nil { panic(err) } fmt.Println("decrypted path: ", decryptedPath) }
Output: root key (32 bytes): 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f path to encrypt: fold1/fold2/fold3/file.txt encrypted path: urxuYzqG_ZlJfBhkGaz87WvvnCZaYD7qf1_ZN_Pd91n5/IyncDwLhWPv4F7EaoUivwICnUeJMWlUnMATL4faaoH2s/_1gitX6uPd3etc3RgoD9R1waT5MPKrlrY32ehz_vqlOv/6qO4DU5AHFabE2r7hmAauvnomvtNByuO-FCw4ch_xaVR3SPE decrypted path: fold1/fold2/fold3/file.txt shared path: _1gitX6uPd3etc3RgoD9R1waT5MPKrlrY32ehz_vqlOv/6qO4DU5AHFabE2r7hmAauvnomvtNByuO-FCw4ch_xaVR3SPE derived key (32 bytes): 909db5ccf2b645e3352ee8212305596ed514d9f84d5acd21d93b4527d2a0c7e1 decrypted path: fold3/file.txt
func EncryptPathRaw ¶ added in v0.14.2
EncryptPathRaw encrypts the path using the provided key directly. EncryptPath should be preferred if possible.
func EncryptSecretBox ¶
func EncryptSecretBox(data []byte, key *storj.Key, nonce *storj.Nonce) (cipherData []byte, err error)
EncryptSecretBox encrypts byte data with a key and nonce. The cipher data is returned
func StoreDecryptPath ¶ added in v0.14.2
func StoreDecryptPath(bucket string, path paths.Encrypted, cipher storj.Cipher, store *Store) ( unencPath paths.Unencrypted, err error)
StoreDecryptPath decrypts the path using the provided cipher and looking up keys from the provided store and bucket.
func StoreDeriveContentKey ¶ added in v0.14.2
func StoreDeriveContentKey(bucket string, path paths.Unencrypted, store *Store) (key *storj.Key, err error)
StoreDeriveContentKey returns the content key for the passed in path by looking up the appropriate base key from the store and bucket and deriving the rest.
func StoreDerivePathKey ¶ added in v0.14.2
func StoreDerivePathKey(bucket string, path paths.Unencrypted, store *Store) (key *storj.Key, err error)
StoreDerivePathKey returns the path key for the passed in path by looking up the appropriate base key from the store and bucket and deriving the rest.
func StoreEncryptPath ¶ added in v0.14.2
func StoreEncryptPath(bucket string, path paths.Unencrypted, cipher storj.Cipher, store *Store) ( encPath paths.Encrypted, err error)
StoreEncryptPath encrypts the path using the provided cipher and looking up keys from the provided store and bucket.
func TransformReader ¶
func TransformReader(r io.ReadCloser, t Transformer, startingBlockNum int64) io.ReadCloser
TransformReader applies a Transformer to a Reader. startingBlockNum should probably be 0 unless you know you're already starting at a block offset.
func TransformReaderSize ¶
func TransformReaderSize(r io.ReadCloser, t Transformer, startingBlockNum int64, expectedSize int64) io.ReadCloser
TransformReaderSize creates a TransformReader with expected size, i.e. the number of bytes that is expected to be read from this reader. If less than the expected bytes are read, the reader will return io.ErrUnexpectedEOF instead of io.EOF.
Types ¶
type AESGCMNonce ¶
type AESGCMNonce [AESGCMNonceSize]byte
AESGCMNonce represents the nonce used by the AES-GCM protocol
func ToAESGCMNonce ¶
func ToAESGCMNonce(nonce *storj.Nonce) *AESGCMNonce
ToAESGCMNonce returns the nonce as a AES-GCM nonce
type Base ¶ added in v0.14.2
Base represents a key with which to derive further keys at some encrypted/unencrypted path.
type NoopTransformer ¶
type NoopTransformer struct{}
NoopTransformer is a dummy Transformer that passes data through without modifying it
func (*NoopTransformer) OutBlockSize ¶
func (t *NoopTransformer) OutBlockSize() int
OutBlockSize is 1
type Store ¶ added in v0.14.2
type Store struct {
// contains filtered or unexported fields
}
The Store allows one to find the matching most encrypted key and path for some unencrypted path. It also reports a mapping of encrypted to unencrypted paths at the searched for unencrypted path.
For example, if the Store contains the mappings
b1, u1/u2/u3 => <e1/e2/e3, k3> b1, u1/u2/u3/u4 => <e1/e2/e3/e4, k4> b1, u1/u5 => <e1/e5, k5> b1, u6 => <e6, k6> b1, u6/u7/u8 => <e6/e7/e8, k8> b2, u1 => <e1', k1'>
Then the following lookups have outputs
b1, u1 => <{e2:u2, e5:u5}, u1, nil> b1, u1/u2/u3 => <{e4:u4}, u1/u2/u3, <u1/u2/u3, e1/e2/e3, k3>> b1, u1/u2/u3/u6 => <{}, u1/u2/u3/, <u1/u2/u3, e1/e2/e3, k3>> b1, u1/u2/u3/u4 => <{}, u1/u2/u3/u4, <u1/u2/u3/u4, e1/e2/e3/e4, k4>> b1, u6/u7 => <{e8:u8}, u6/, <u6, e6, k6>> b2, u1 => <{}, u1, <u1, e1', k1'>>
Example ¶
s := NewStore() ep := paths.NewEncrypted up := paths.NewUnencrypted // Add a fairly complicated tree to the store. abortIfError(s.Add("b1", up("u1/u2/u3"), ep("e1/e2/e3"), toKey("k3"))) abortIfError(s.Add("b1", up("u1/u2/u3/u4"), ep("e1/e2/e3/e4"), toKey("k4"))) abortIfError(s.Add("b1", up("u1/u5"), ep("e1/e5"), toKey("k5"))) abortIfError(s.Add("b1", up("u6"), ep("e6"), toKey("k6"))) abortIfError(s.Add("b1", up("u6/u7/u8"), ep("e6/e7/e8"), toKey("k8"))) abortIfError(s.Add("b2", up("u1"), ep("e1'"), toKey("k1"))) abortIfError(s.Add("b3", paths.Unencrypted{}, paths.Encrypted{}, toKey("m1"))) // Look up some complicated queries by the unencrypted path. printLookup(s.LookupUnencrypted("b1", up("u1"))) printLookup(s.LookupUnencrypted("b1", up("u1/u2/u3"))) printLookup(s.LookupUnencrypted("b1", up("u1/u2/u3/u6"))) printLookup(s.LookupUnencrypted("b1", up("u1/u2/u3/u4"))) printLookup(s.LookupUnencrypted("b1", up("u6/u7"))) printLookup(s.LookupUnencrypted("b2", up("u1"))) printLookup(s.LookupUnencrypted("b3", paths.Unencrypted{})) printLookup(s.LookupUnencrypted("b3", up("z1"))) fmt.Println() // Look up some complicated queries by the encrypted path. printLookup(s.LookupEncrypted("b1", ep("e1"))) printLookup(s.LookupEncrypted("b1", ep("e1/e2/e3"))) printLookup(s.LookupEncrypted("b1", ep("e1/e2/e3/e6"))) printLookup(s.LookupEncrypted("b1", ep("e1/e2/e3/e4"))) printLookup(s.LookupEncrypted("b1", ep("e6/e7"))) printLookup(s.LookupEncrypted("b2", ep("e1'"))) printLookup(s.LookupEncrypted("b3", paths.Encrypted{})) printLookup(s.LookupEncrypted("b3", ep("z1")))
Output: <map["e2":"u2" "e5":"u5"], "u1", nil> <map["e4":"u4"], "u1/u2/u3", <"u1/u2/u3", "e1/e2/e3", "k3">> <map[], "u1/u2/u3/", <"u1/u2/u3", "e1/e2/e3", "k3">> <map[], "u1/u2/u3/u4", <"u1/u2/u3/u4", "e1/e2/e3/e4", "k4">> <map["e8":"u8"], "u6/", <"u6", "e6", "k6">> <map[], "u1", <"u1", "e1'", "k1">> <map[], "", <"", "", "m1">> <map[], "", <"", "", "m1">> <map["u2":"e2" "u5":"e5"], "e1", nil> <map["u4":"e4"], "e1/e2/e3", <"u1/u2/u3", "e1/e2/e3", "k3">> <map[], "e1/e2/e3/", <"u1/u2/u3", "e1/e2/e3", "k3">> <map[], "e1/e2/e3/e4", <"u1/u2/u3/u4", "e1/e2/e3/e4", "k4">> <map["u8":"e8"], "e6/", <"u6", "e6", "k6">> <map[], "e1'", <"u1", "e1'", "k1">> <map[], "", <"", "", "m1">> <map[], "", <"", "", "m1">>
func (*Store) Add ¶ added in v0.14.2
func (s *Store) Add(bucket string, unenc paths.Unencrypted, enc paths.Encrypted, key storj.Key) error
Add creates a mapping from the unencrypted path to the encrypted path and key.
func (*Store) GetDefaultKey ¶ added in v0.14.4
GetDefaultKey returns the default key, or nil if none has been set.
func (*Store) Iterate ¶ added in v0.14.4
Iterate executes the callback with every value that has been Added to the Store.
func (*Store) LookupEncrypted ¶ added in v0.14.2
func (s *Store) LookupEncrypted(bucket string, path paths.Encrypted) ( revealed map[string]string, consumed paths.Encrypted, base *Base)
LookupEncrypted finds the matching most encrypted path added to the Store, reports how much of the path matched, any known encrypted paths at the requested path, and if a key an encrypted path exists for some prefix of the encrypted path.
func (*Store) LookupUnencrypted ¶ added in v0.14.2
func (s *Store) LookupUnencrypted(bucket string, path paths.Unencrypted) ( revealed map[string]string, consumed paths.Unencrypted, base *Base)
LookupUnencrypted finds the matching most unencrypted path added to the Store, reports how much of the path matched, any known unencrypted paths at the requested path, and if a key and encrypted path exists for some prefix of the unencrypted path.
func (*Store) SetDefaultKey ¶ added in v0.14.2
SetDefaultKey adds a default key to be returned for any lookup that does not match a bucket.
type Transformer ¶
type Transformer interface { InBlockSize() int // The block size prior to transformation OutBlockSize() int // The block size after transformation Transform(out, in []byte, blockNum int64) ([]byte, error) }
A Transformer is a data transformation that may change the size of the blocks of data it operates on in a deterministic fashion.
func NewAESGCMDecrypter ¶
func NewAESGCMDecrypter(key *storj.Key, startingNonce *AESGCMNonce, encryptedBlockSize int) (Transformer, error)
NewAESGCMDecrypter returns a Transformer that decrypts the data passing through with key. See the comments for NewAESGCMEncrypter about startingNonce.
func NewAESGCMEncrypter ¶
func NewAESGCMEncrypter(key *storj.Key, startingNonce *AESGCMNonce, encryptedBlockSize int) (Transformer, error)
NewAESGCMEncrypter returns a Transformer that encrypts the data passing through with key.
startingNonce is treated as a big-endian encoded unsigned integer, and as blocks pass through, their block number and the starting nonce is added together to come up with that block's nonce. Encrypting different data with the same key and the same nonce is a huge security issue. It's safe to always encode new data with a random key and random startingNonce. The monotonically-increasing nonce (that rolls over) is to protect against data reordering.
When in doubt, generate a new key from crypto/rand and a startingNonce from crypto/rand as often as possible.
func NewDecrypter ¶
func NewDecrypter(cipher storj.Cipher, key *storj.Key, startingNonce *storj.Nonce, encryptedBlockSize int) (Transformer, error)
NewDecrypter creates a Transformer using the given cipher, key and nonce to decrypt data passing through it
func NewEncrypter ¶
func NewEncrypter(cipher storj.Cipher, key *storj.Key, startingNonce *storj.Nonce, encryptedBlockSize int) (Transformer, error)
NewEncrypter creates a Transformer using the given cipher, key and nonce to encrypt data passing through it
func NewSecretboxDecrypter ¶
func NewSecretboxDecrypter(key *storj.Key, startingNonce *storj.Nonce, encryptedBlockSize int) (Transformer, error)
NewSecretboxDecrypter returns a Transformer that decrypts the data passing through with key. See the comments for NewSecretboxEncrypter about startingNonce.
func NewSecretboxEncrypter ¶
func NewSecretboxEncrypter(key *storj.Key, startingNonce *storj.Nonce, encryptedBlockSize int) (Transformer, error)
NewSecretboxEncrypter returns a Transformer that encrypts the data passing through with key.
startingNonce is treated as a big-endian encoded unsigned integer, and as blocks pass through, their block number and the starting nonce is added together to come up with that block's nonce. Encrypting different data with the same key and the same nonce is a huge security issue. It's safe to always encode new data with a random key and random startingNonce. The monotonically-increasing nonce (that rolls over) is to protect against data reordering.
When in doubt, generate a new key from crypto/rand and a startingNonce from crypto/rand as often as possible.