Modify steel crypt to expose a hashBytes function that does not assume the encoding of the inputs or output

This commit is contained in:
Vishnu Mohandas 2020-09-09 14:35:24 +05:30
parent 3a539ea0aa
commit 1f98f8ca8d
5 changed files with 31 additions and 22 deletions

View file

@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:io' as io;
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
@ -43,15 +44,15 @@ class Configuration {
Future<KeyAttributes> generateAndSaveKey(String passphrase) async {
final key = CryptoUtil.getBase64EncodedSecureRandomString(length: 32);
final kekSalt = CryptoUtil.getBase64EncodedSecureRandomString(length: 32);
final kek = CryptoUtil.scrypt(passphrase, kekSalt, 32);
final kekHashSalt =
CryptoUtil.getBase64EncodedSecureRandomString(length: 32);
final kekHash = CryptoUtil.scrypt(kek, kekHashSalt, 32);
final kekSalt = CryptoUtil.getSecureRandomBytes(length: 32);
final kek = CryptoUtil.scrypt(utf8.encode(passphrase), kekSalt);
final kekHashSalt = CryptoUtil.getSecureRandomBytes(length: 32);
final kekHash = CryptoUtil.scrypt(kek, kekHashSalt);
final iv = CryptoUtil.getBase64EncodedSecureRandomString(length: 16);
final encryptedKey = CryptoUtil.encryptToBase64(key, kek, iv);
final attributes =
KeyAttributes(kekSalt, kekHash, kekHashSalt, encryptedKey, iv);
final encryptedKey =
CryptoUtil.encryptToBase64(key, base64.encode(kek), iv);
final attributes = KeyAttributes(base64.encode(kekSalt),
base64.encode(kekHash), base64.encode(kekHashSalt), encryptedKey, iv);
await setKey(key);
await setKeyAttributes(attributes);
return attributes;
@ -59,14 +60,17 @@ class Configuration {
Future<void> decryptAndSaveKey(
String passphrase, KeyAttributes attributes) async {
final kek = CryptoUtil.scrypt(passphrase, attributes.kekSalt, 32);
bool correctPassphrase =
CryptoUtil.compareHash(kek, attributes.kekHash, attributes.kekHashSalt);
final kek = CryptoUtil.scrypt(
utf8.encode(passphrase), base64.decode(attributes.kekSalt));
bool correctPassphrase = CryptoUtil.compareHash(
kek,
base64.decode(attributes.kekHash),
base64.decode(attributes.kekHashSalt));
if (!correctPassphrase) {
throw Exception("Incorrect passphrase");
}
final key = CryptoUtil.decryptFromBase64(
attributes.encryptedKey, kek, attributes.encryptedKeyIV);
attributes.encryptedKey, base64.encode(kek), attributes.encryptedKeyIV);
await setKey(key);
}

View file

@ -15,14 +15,17 @@ class CryptoUtil {
return SecureRandom(length).base64;
}
static String scrypt(String passphrase, String salt, int length) {
return steel.PassCrypt.scrypt()
.hash(salt: salt, inp: passphrase, len: length);
static Uint8List getSecureRandomBytes({int length = 32}) {
return SecureRandom(length).bytes;
}
static bool compareHash(String plainText, String hash, String salt) {
static Uint8List scrypt(Uint8List plainText, Uint8List salt) {
return steel.PassCrypt.scrypt()
.check(plain: plainText, hashed: hash, salt: salt);
.hashBytes(salt: salt, input: plainText, len: 32);
}
static bool compareHash(Uint8List plainText, Uint8List hash, Uint8List salt) {
return base64.encode(scrypt(plainText, salt)) == base64.encode(hash);
}
static String encryptToBase64(

View file

@ -675,10 +675,10 @@ packages:
steel_crypt:
dependency: "direct main"
description:
name: steel_crypt
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.2+1"
path: "thirdparty/steel_crypt"
relative: true
source: path
version: "2.2.2"
stream_channel:
dependency: transitive
description:

View file

@ -65,7 +65,8 @@ dependencies:
flutter_svg: ^0.18.1
crisp: ^0.1.3
uuid: 2.2.2
steel_crypt: ^2.2.2+1
steel_crypt:
path: thirdparty/steel_crypt
dev_dependencies:
flutter_test:

1
thirdparty/steel_crypt vendored Submodule

@ -0,0 +1 @@
Subproject commit e3e3603b571e8b51a7166f2a7a48c11e0d0b1c7e