Default to sensitive limits for computation and memory for key derivation
This commit is contained in:
parent
317bbf8f18
commit
8cb7f885b3
|
@ -114,7 +114,26 @@ class Configuration {
|
|||
// Derive a key from the password that will be used to encrypt and
|
||||
// decrypt the master key
|
||||
final kekSalt = CryptoUtil.getSaltToDeriveKey();
|
||||
final kek = CryptoUtil.deriveKey(utf8.encode(password), kekSalt);
|
||||
int memLimit = Sodium.cryptoPwhashMemlimitSensitive;
|
||||
final opsLimit = Sodium.cryptoPwhashOpslimitSensitive;
|
||||
var kek;
|
||||
try {
|
||||
kek = await CryptoUtil.deriveKey(
|
||||
utf8.encode(password),
|
||||
kekSalt,
|
||||
memLimit,
|
||||
opsLimit,
|
||||
);
|
||||
} catch (e) {
|
||||
_logger.info("Reducing memory utilization");
|
||||
memLimit = Sodium.cryptoPwhashMemlimitModerate;
|
||||
kek = await CryptoUtil.deriveKey(
|
||||
utf8.encode(password),
|
||||
kekSalt,
|
||||
memLimit,
|
||||
opsLimit,
|
||||
);
|
||||
}
|
||||
|
||||
// Encrypt the key with this derived key
|
||||
final encryptedKeyData = CryptoUtil.encryptSync(key, kek);
|
||||
|
@ -130,6 +149,8 @@ class Configuration {
|
|||
Sodium.bin2base64(keyPair.pk),
|
||||
Sodium.bin2base64(encryptedSecretKeyData.encryptedData),
|
||||
Sodium.bin2base64(encryptedSecretKeyData.nonce),
|
||||
memLimit,
|
||||
opsLimit,
|
||||
);
|
||||
final privateAttributes = PrivateKeyAttributes(
|
||||
Sodium.bin2base64(key), Sodium.bin2base64(keyPair.sk));
|
||||
|
@ -138,8 +159,12 @@ class Configuration {
|
|||
|
||||
Future<void> decryptAndSaveKey(
|
||||
String password, KeyAttributes attributes) async {
|
||||
final kek = CryptoUtil.deriveKey(
|
||||
utf8.encode(password), Sodium.base642bin(attributes.kekSalt));
|
||||
final kek = await CryptoUtil.deriveKey(
|
||||
utf8.encode(password),
|
||||
Sodium.base642bin(attributes.kekSalt),
|
||||
attributes.memLimit,
|
||||
attributes.opsLimit,
|
||||
);
|
||||
var key;
|
||||
try {
|
||||
key = CryptoUtil.decryptSync(Sodium.base642bin(attributes.encryptedKey),
|
||||
|
|
|
@ -7,6 +7,8 @@ class KeyAttributes {
|
|||
final String publicKey;
|
||||
final String encryptedSecretKey;
|
||||
final String secretKeyDecryptionNonce;
|
||||
final int memLimit;
|
||||
final int opsLimit;
|
||||
|
||||
KeyAttributes(
|
||||
this.kekSalt,
|
||||
|
@ -15,26 +17,10 @@ class KeyAttributes {
|
|||
this.publicKey,
|
||||
this.encryptedSecretKey,
|
||||
this.secretKeyDecryptionNonce,
|
||||
this.memLimit,
|
||||
this.opsLimit,
|
||||
);
|
||||
|
||||
KeyAttributes copyWith({
|
||||
String kekSalt,
|
||||
String encryptedKey,
|
||||
String keyDecryptionNonce,
|
||||
String publicKey,
|
||||
String encryptedSecretKey,
|
||||
String secretKeyDecryptionNonce,
|
||||
}) {
|
||||
return KeyAttributes(
|
||||
kekSalt ?? this.kekSalt,
|
||||
encryptedKey ?? this.encryptedKey,
|
||||
keyDecryptionNonce ?? this.keyDecryptionNonce,
|
||||
publicKey ?? this.publicKey,
|
||||
encryptedSecretKey ?? this.encryptedSecretKey,
|
||||
secretKeyDecryptionNonce ?? this.secretKeyDecryptionNonce,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'kekSalt': kekSalt,
|
||||
|
@ -43,6 +29,8 @@ class KeyAttributes {
|
|||
'publicKey': publicKey,
|
||||
'encryptedSecretKey': encryptedSecretKey,
|
||||
'secretKeyDecryptionNonce': secretKeyDecryptionNonce,
|
||||
'memLimit': memLimit,
|
||||
'opsLimit': opsLimit,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -56,6 +44,8 @@ class KeyAttributes {
|
|||
map['publicKey'],
|
||||
map['encryptedSecretKey'],
|
||||
map['secretKeyDecryptionNonce'],
|
||||
map['memLimit'],
|
||||
map['opsLimit'],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -63,32 +53,4 @@ class KeyAttributes {
|
|||
|
||||
factory KeyAttributes.fromJson(String source) =>
|
||||
KeyAttributes.fromMap(json.decode(source));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'KeyAttributes(kekSalt: $kekSalt, encryptedKey: $encryptedKey, keyDecryptionNonce: $keyDecryptionNonce, publicKey: $publicKey, encryptedSecretKey: $encryptedSecretKey, secretKeyDecryptionNonce: $secretKeyDecryptionNonce)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object o) {
|
||||
if (identical(this, o)) return true;
|
||||
|
||||
return o is KeyAttributes &&
|
||||
o.kekSalt == kekSalt &&
|
||||
o.encryptedKey == encryptedKey &&
|
||||
o.keyDecryptionNonce == keyDecryptionNonce &&
|
||||
o.publicKey == publicKey &&
|
||||
o.encryptedSecretKey == encryptedSecretKey &&
|
||||
o.secretKeyDecryptionNonce == secretKeyDecryptionNonce;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return kekSalt.hashCode ^
|
||||
encryptedKey.hashCode ^
|
||||
keyDecryptionNonce.hashCode ^
|
||||
publicKey.hashCode ^
|
||||
encryptedSecretKey.hashCode ^
|
||||
secretKeyDecryptionNonce.hashCode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,17 @@ Uint8List cryptoSecretboxOpenEasy(Map<String, dynamic> args) {
|
|||
args["cipher"], args["nonce"], args["key"]);
|
||||
}
|
||||
|
||||
Uint8List cryptoPwHash(Map<String, dynamic> args) {
|
||||
return Sodium.cryptoPwhash(
|
||||
Sodium.cryptoSecretboxKeybytes,
|
||||
args["password"],
|
||||
args["salt"],
|
||||
args["opsLimit"],
|
||||
args["memLimit"],
|
||||
Sodium.cryptoPwhashAlgDefault,
|
||||
);
|
||||
}
|
||||
|
||||
EncryptionResult chachaEncryptFile(Map<String, dynamic> args) {
|
||||
final encryptionStartTime = DateTime.now().millisecondsSinceEpoch;
|
||||
final logger = Logger("ChaChaEncrypt");
|
||||
|
@ -183,14 +194,18 @@ class CryptoUtil {
|
|||
return Sodium.randombytesBuf(Sodium.cryptoPwhashSaltbytes);
|
||||
}
|
||||
|
||||
static Uint8List deriveKey(Uint8List password, Uint8List salt) {
|
||||
return Sodium.cryptoPwhash(
|
||||
Sodium.cryptoSecretboxKeybytes,
|
||||
password,
|
||||
salt,
|
||||
Sodium.cryptoPwhashOpslimitInteractive,
|
||||
Sodium.cryptoPwhashMemlimitInteractive,
|
||||
Sodium.cryptoPwhashAlgDefault);
|
||||
static Future<Uint8List> deriveKey(
|
||||
Uint8List password,
|
||||
Uint8List salt,
|
||||
int memLimit,
|
||||
int opsLimit,
|
||||
) {
|
||||
return _computer.compute(cryptoPwHash, param: {
|
||||
"password": password,
|
||||
"salt": salt,
|
||||
"memLimit": memLimit,
|
||||
"opsLimit": opsLimit,
|
||||
});
|
||||
}
|
||||
|
||||
static Future<KeyPair> generateKeyPair() async {
|
||||
|
|
Loading…
Reference in a new issue