Browse Source

support for AES-KDF in kdbx 4.x #4

remove-cryptography-dependency
Herbert Poul 5 years ago
parent
commit
62c1a72ba9
  1. 2
      .gitignore
  2. 21
      lib/src/crypto/key_encrypter_kdf.dart
  3. 2
      lib/src/internal/crypto_utils.dart
  4. BIN
      test/aeskdf.kdbx
  5. 6
      test/kdbx4_test.dart
  6. BIN
      test_output_chacha20.kdbx

2
.gitignore vendored

@ -45,4 +45,4 @@ doc/api/
/test.kdbx /test.kdbx
/test_v4.kdbx /test_v4.kdbx
/test_v4x.kdbx /test_v4x.kdbx
/test_output*.kdbx

21
lib/src/crypto/key_encrypter_kdf.dart

@ -1,11 +1,14 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:crypto/crypto.dart' as crypto;
import 'package:kdbx/kdbx.dart'; import 'package:kdbx/kdbx.dart';
import 'package:kdbx/src/crypto/argon2.dart'; import 'package:kdbx/src/crypto/argon2.dart';
import 'package:kdbx/src/internal/byte_utils.dart'; import 'package:kdbx/src/internal/byte_utils.dart';
import 'package:kdbx/src/internal/crypto_utils.dart';
import 'package:kdbx/src/kdbx_var_dictionary.dart'; import 'package:kdbx/src/kdbx_var_dictionary.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:pointycastle/export.dart';
final _logger = Logger('key_encrypter_kdf'); final _logger = Logger('key_encrypter_kdf');
@ -88,9 +91,10 @@ class KeyEncrypterKdf {
break; break;
case KdfType.Aes: case KdfType.Aes:
_logger.fine('Must be using aes'); _logger.fine('Must be using aes');
break; return encryptAes(key, kdfParameters);
} }
throw UnsupportedError('unsupported encrypt stuff.'); throw UnsupportedError(
'unsupported KDF Type UUID ${ByteUtils.toHexList(uuid)}.');
} }
Uint8List encryptArgon2(Uint8List key, VarDictionary kdfParameters) { Uint8List encryptArgon2(Uint8List key, VarDictionary kdfParameters) {
@ -106,4 +110,17 @@ class KeyEncrypterKdf {
KdfField.version.read(kdfParameters), KdfField.version.read(kdfParameters),
); );
} }
Uint8List encryptAes(Uint8List key, VarDictionary kdfParameters) {
final encryptionKey = KdfField.salt.read(kdfParameters);
final rounds = KdfField.rounds.read(kdfParameters);
assert(encryptionKey.length == 32);
final cipher = ECBBlockCipher(AESFastEngine())
..init(true, KeyParameter(encryptionKey));
var transformedKey = key;
for (int i = 0; i < rounds; i++) {
transformedKey = AesHelper.processBlocks(cipher, transformedKey);
}
return crypto.sha256.convert(transformedKey).bytes as Uint8List;
}
} }

2
lib/src/internal/crypto_utils.dart

@ -20,7 +20,7 @@ class AesHelper {
final Pbkdf2Parameters params = final Pbkdf2Parameters params =
Pbkdf2Parameters(salt, iterationCount, derivedKeyLength); Pbkdf2Parameters(salt, iterationCount, derivedKeyLength);
final KeyDerivator keyDerivator = final KeyDerivator keyDerivator =
PBKDF2KeyDerivator(HMac(SHA256Digest(), 16)); PBKDF2KeyDerivator(HMac(SHA256Digest(), 64));
keyDerivator.init(params); keyDerivator.init(params);
return keyDerivator.process(password); return keyDerivator.process(password);

BIN
test/aeskdf.kdbx

Binary file not shown.

6
test/kdbx4_test.dart

@ -94,6 +94,12 @@ void main() {
kdbxFormat.read(data, Credentials(ProtectedValue.fromString('asdf'))); kdbxFormat.read(data, Credentials(ProtectedValue.fromString('asdf')));
expect(file.body.rootGroup.entries, hasLength(1)); expect(file.body.rootGroup.entries, hasLength(1));
}); });
test('Reading aes-kdf', () async {
final data = await File('test/aeskdf.kdbx').readAsBytes();
final file =
kdbxFormat.read(data, Credentials(ProtectedValue.fromString('asdf')));
expect(file.body.rootGroup.entries, hasLength(1));
});
}); });
group('Writing', () { group('Writing', () {
test('Create and save', () { test('Create and save', () {

BIN
test_output_chacha20.kdbx

Binary file not shown.
Loading…
Cancel
Save