Преглед изворни кода

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

Vishnu Mohandas пре 4 година
родитељ
комит
1f98f8ca8d
5 измењених фајлова са 31 додато и 22 уклоњено
  1. 16 12
      lib/core/configuration.dart
  2. 8 5
      lib/utils/crypto_util.dart
  3. 4 4
      pubspec.lock
  4. 2 1
      pubspec.yaml
  5. 1 0
      thirdparty/steel_crypt

+ 16 - 12
lib/core/configuration.dart

@@ -1,3 +1,4 @@
+import 'dart:convert';
 import 'dart:io' as io;
 import 'dart:io' as io;
 
 
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
@@ -43,15 +44,15 @@ class Configuration {
 
 
   Future<KeyAttributes> generateAndSaveKey(String passphrase) async {
   Future<KeyAttributes> generateAndSaveKey(String passphrase) async {
     final key = CryptoUtil.getBase64EncodedSecureRandomString(length: 32);
     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 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 setKey(key);
     await setKeyAttributes(attributes);
     await setKeyAttributes(attributes);
     return attributes;
     return attributes;
@@ -59,14 +60,17 @@ class Configuration {
 
 
   Future<void> decryptAndSaveKey(
   Future<void> decryptAndSaveKey(
       String passphrase, KeyAttributes attributes) async {
       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) {
     if (!correctPassphrase) {
       throw Exception("Incorrect passphrase");
       throw Exception("Incorrect passphrase");
     }
     }
     final key = CryptoUtil.decryptFromBase64(
     final key = CryptoUtil.decryptFromBase64(
-        attributes.encryptedKey, kek, attributes.encryptedKeyIV);
+        attributes.encryptedKey, base64.encode(kek), attributes.encryptedKeyIV);
     await setKey(key);
     await setKey(key);
   }
   }
 
 

+ 8 - 5
lib/utils/crypto_util.dart

@@ -15,14 +15,17 @@ class CryptoUtil {
     return SecureRandom(length).base64;
     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()
     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(
   static String encryptToBase64(

+ 4 - 4
pubspec.lock

@@ -675,10 +675,10 @@ packages:
   steel_crypt:
   steel_crypt:
     dependency: "direct main"
     dependency: "direct main"
     description:
     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:
   stream_channel:
     dependency: transitive
     dependency: transitive
     description:
     description:

+ 2 - 1
pubspec.yaml

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

+ 1 - 0
thirdparty/steel_crypt

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