mirror of
https://github.com/kopia/kopia.git
synced 2026-05-24 14:44:47 -04:00
added SCrypt
This commit is contained in:
@@ -4,32 +4,39 @@
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/crypto/scrypt"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
)
|
||||
|
||||
const (
|
||||
passwordBasedKeySize = 32
|
||||
|
||||
pbkdf2Rounds = 10000
|
||||
|
||||
// MinPasswordLength is the minimum allowed length of a password in charcters.
|
||||
MinPasswordLength = 12
|
||||
|
||||
// MinMasterKeyLength is the minimum allowed length of a master key, in bytes.
|
||||
MinMasterKeyLength = 16
|
||||
|
||||
defaultKeyAlgorithm = "scrypt-65536-8-1"
|
||||
)
|
||||
|
||||
var SupportedKeyAlgorithms = []string{
|
||||
"scrypt-65536-8-1",
|
||||
"pbkdf2-sha256-100000",
|
||||
}
|
||||
|
||||
// Credentials encapsulates credentials used to encrypt a Vault.
|
||||
type Credentials interface {
|
||||
getMasterKey(salt []byte) []byte
|
||||
getMasterKey(f *Format) ([]byte, error)
|
||||
}
|
||||
|
||||
type masterKeyCredentials struct {
|
||||
key []byte
|
||||
}
|
||||
|
||||
func (mkc *masterKeyCredentials) getMasterKey(salt []byte) []byte {
|
||||
return mkc.key
|
||||
func (mkc *masterKeyCredentials) getMasterKey(f *Format) ([]byte, error) {
|
||||
return mkc.key, nil
|
||||
}
|
||||
|
||||
// MasterKey returns master key-based Credentials with the specified key.
|
||||
@@ -45,8 +52,17 @@ type passwordCredentials struct {
|
||||
password string
|
||||
}
|
||||
|
||||
func (pc *passwordCredentials) getMasterKey(salt []byte) []byte {
|
||||
return pbkdf2.Key([]byte(pc.password), salt, pbkdf2Rounds, passwordBasedKeySize, sha256.New)
|
||||
func (pc *passwordCredentials) getMasterKey(f *Format) ([]byte, error) {
|
||||
switch f.KeyAlgo {
|
||||
case "pbkdf2-sha256-100000":
|
||||
return pbkdf2.Key([]byte(pc.password), f.UniqueID, 100000, passwordBasedKeySize, sha256.New), nil
|
||||
|
||||
case "scrypt-65536-8-1":
|
||||
return scrypt.Key([]byte(pc.password), f.UniqueID, 65536, 8, 1, passwordBasedKeySize)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported key algorithm: %v", f.KeyAlgo)
|
||||
}
|
||||
}
|
||||
|
||||
// Password returns password-based Credentials with the specified password.
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
type Format struct {
|
||||
Version string `json:"version"`
|
||||
UniqueID []byte `json:"uniqueID"`
|
||||
KeyAlgo string `json:"keyAlgo"`
|
||||
Encryption string `json:"encryption"`
|
||||
Checksum string `json:"checksum"`
|
||||
}
|
||||
|
||||
@@ -284,7 +284,15 @@ func Create(
|
||||
if _, err := io.ReadFull(rand.Reader, v.format.UniqueID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v.masterKey = vaultCreds.getMasterKey(v.format.UniqueID)
|
||||
if v.format.KeyAlgo == "" {
|
||||
v.format.KeyAlgo = defaultKeyAlgorithm
|
||||
|
||||
}
|
||||
var err error
|
||||
v.masterKey, err = vaultCreds.getMasterKey(&v.format)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
formatBytes, err := json.Marshal(&v.format)
|
||||
if err != nil {
|
||||
@@ -367,7 +375,10 @@ func Open(vaultStorage blob.Storage, vaultCreds Credentials) (*Vault, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v.masterKey = vaultCreds.getMasterKey(v.format.UniqueID)
|
||||
v.masterKey, err = vaultCreds.getMasterKey(&v.format)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v.itemPrefix = prefix
|
||||
|
||||
cfgData, err := v.decryptBlock(blocks[offset+1])
|
||||
|
||||
Reference in New Issue
Block a user