Hash KEK instead of the passphrase

This commit is contained in:
Vishnu Mohandas 2020-10-01 00:01:04 +05:30
parent 1b40d64a20
commit 0d1473708c
3 changed files with 46 additions and 42 deletions

View file

@ -21,8 +21,10 @@ class Configuration {
static const hasOptedForE2EKey = "has_opted_for_e2e_encryption";
static const foldersToBackUpKey = "folders_to_back_up";
static const keyKey = "key";
static const kekSaltKey = "kek_salt";
static const kekHashKey = "kek_hash";
static const encryptedKeyKey = "encrypted_key";
static const keyAttributesKey = "key_attributes";
static const keyDecryptionNonceKey = "key_decryption_nonce";
SharedPreferences _preferences;
FlutterSecureStorage _secureStorage;
@ -55,12 +57,12 @@ class Configuration {
final encryptedKeyData = await CryptoUtil.encrypt(key, key: kek);
// Hash the passphrase so that its correctness can be compared later
final passphraseHash = CryptoUtil.hash(utf8.encode(passphrase));
final kekHash = await CryptoUtil.hash(kek);
final attributes = KeyAttributes(
passphraseHash: passphraseHash,
kekSalt: Sodium.bin2base64(kekSalt),
encryptedKey: encryptedKeyData.encryptedData.base64,
keyDecryptionNonce: encryptedKeyData.nonce.base64,
Sodium.bin2base64(kekSalt),
kekHash,
encryptedKeyData.encryptedData.base64,
encryptedKeyData.nonce.base64,
);
await setKey(Sodium.bin2base64(key));
await setKeyAttributes(attributes);
@ -69,14 +71,13 @@ class Configuration {
Future<void> decryptAndSaveKey(
String passphrase, KeyAttributes attributes) async {
final passphraseBytes = utf8.encode(passphrase);
final kek = CryptoUtil.deriveKey(
utf8.encode(passphrase), Sodium.base642bin(attributes.kekSalt));
bool correctPassphrase =
CryptoUtil.verifyHash(passphraseBytes, attributes.passphraseHash);
await CryptoUtil.verifyHash(kek, attributes.kekHash);
if (!correctPassphrase) {
throw Exception("Incorrect passphrase");
}
final kek = CryptoUtil.deriveKey(
passphraseBytes, Sodium.base642bin(attributes.kekSalt));
final key = await CryptoUtil.decrypt(
Sodium.base642bin(attributes.encryptedKey),
kek,
@ -85,7 +86,8 @@ class Configuration {
}
String getHttpEndpoint() {
return "https://api.staging.ente.io";
return "http://192.168.0.100";
// return "https://api.staging.ente.io";
}
Future<void> setEndpoint(String endpoint) async {
@ -145,19 +147,22 @@ class Configuration {
Future<void> setKeyAttributes(KeyAttributes attributes) async {
await _preferences.setString(
keyAttributesKey, attributes == null ? null : attributes.toJson());
await setEncryptedKey(attributes == null ? null : attributes.encryptedKey);
kekSaltKey, attributes == null ? null : attributes.kekSalt);
await _preferences.setString(
kekHashKey, attributes == null ? null : attributes.kekHash);
await _preferences.setString(
encryptedKeyKey, attributes == null ? null : attributes.encryptedKey);
await _preferences.setString(keyDecryptionNonceKey,
attributes == null ? null : attributes.keyDecryptionNonce);
}
KeyAttributes getKeyAttributes() {
if (_preferences.getString(keyAttributesKey) == null) {
return null;
}
return KeyAttributes.fromJson(_preferences.getString(keyAttributesKey));
}
Future<void> setEncryptedKey(String encryptedKey) async {
await _preferences.setString(encryptedKeyKey, encryptedKey);
return KeyAttributes(
_preferences.getString(kekSaltKey),
_preferences.getString(kekHashKey),
_preferences.getString(encryptedKeyKey),
_preferences.getString(keyDecryptionNonceKey),
);
}
String getEncryptedKey() {

View file

@ -1,36 +1,36 @@
import 'dart:convert';
class KeyAttributes {
final String passphraseHash;
final String kekSalt;
final String kekHash;
final String encryptedKey;
final String keyDecryptionNonce;
KeyAttributes({
this.passphraseHash,
KeyAttributes(
this.kekSalt,
this.kekHash,
this.encryptedKey,
this.keyDecryptionNonce,
});
);
KeyAttributes copyWith({
String passphraseHash,
String kekSalt,
String kekHash,
String encryptedKey,
String keyDecryptionNonce,
}) {
return KeyAttributes(
passphraseHash: passphraseHash ?? this.passphraseHash,
kekSalt: kekSalt ?? this.kekSalt,
encryptedKey: encryptedKey ?? this.encryptedKey,
keyDecryptionNonce: keyDecryptionNonce ?? this.keyDecryptionNonce,
kekSalt ?? this.kekSalt,
kekHash ?? this.kekHash,
encryptedKey ?? this.encryptedKey,
keyDecryptionNonce ?? this.keyDecryptionNonce,
);
}
Map<String, dynamic> toMap() {
return {
'passphraseHash': passphraseHash,
'kekSalt': kekSalt,
'kekHash': kekHash,
'encryptedKey': encryptedKey,
'keyDecryptionNonce': keyDecryptionNonce,
};
@ -40,10 +40,10 @@ class KeyAttributes {
if (map == null) return null;
return KeyAttributes(
passphraseHash: map['passphraseHash'],
kekSalt: map['kekSalt'],
encryptedKey: map['encryptedKey'],
keyDecryptionNonce: map['keyDecryptionNonce'],
map['kekSalt'],
map['kekHash'],
map['encryptedKey'],
map['keyDecryptionNonce'],
);
}
@ -54,7 +54,7 @@ class KeyAttributes {
@override
String toString() {
return 'KeyAttributes(passphraseHash: $passphraseHash, kekSalt: $kekSalt, encryptedKey: $encryptedKey, keyDecryptionNonce: $keyDecryptionNonce)';
return 'KeyAttributes(kekSalt: $kekSalt, kekHash: $kekHash, encryptedKey: $encryptedKey, keyDecryptionNonce: $keyDecryptionNonce)';
}
@override
@ -62,16 +62,16 @@ class KeyAttributes {
if (identical(this, o)) return true;
return o is KeyAttributes &&
o.passphraseHash == passphraseHash &&
o.kekSalt == kekSalt &&
o.kekHash == kekHash &&
o.encryptedKey == encryptedKey &&
o.keyDecryptionNonce == keyDecryptionNonce;
}
@override
int get hashCode {
return passphraseHash.hashCode ^
kekSalt.hashCode ^
return kekSalt.hashCode ^
kekHash.hashCode ^
encryptedKey.hashCode ^
keyDecryptionNonce.hashCode;
}

View file

@ -301,9 +301,8 @@ class DebugWidget extends StatelessWidget {
Text("KEK Salt", style: TextStyle(fontWeight: FontWeight.bold)),
Text(keyAttributes.kekSalt),
Padding(padding: EdgeInsets.all(12)),
Text("Passphrase Hash",
style: TextStyle(fontWeight: FontWeight.bold)),
Text(keyAttributes.passphraseHash),
Text("KEK Hash", style: TextStyle(fontWeight: FontWeight.bold)),
Text(keyAttributes.kekHash),
Padding(padding: EdgeInsets.all(12)),
]),
),