Skip to content

Commit 69986b2

Browse files
committed
Updated flutter_string_encryption. Authentication almost done.
1 parent a39a5bd commit 69986b2

File tree

3 files changed

+79
-73
lines changed

3 files changed

+79
-73
lines changed

lib/LoginPage.dart

Lines changed: 75 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
33
import 'package:flutter_string_encryption/flutter_string_encryption.dart';
44
import 'package:shared_preferences/shared_preferences.dart';
55
import 'package:crypt/crypt.dart';
6-
import 'dart:math';
76

87
// TODO: animated feedback when decrypting (spinning loader or something)
98

@@ -28,14 +27,14 @@ class _LoginPageState extends State<LoginPage> {
2827

2928
final TextEditingController textEditingController = new TextEditingController();
3029

31-
Set<String> _noteIDs = new Set();
30+
// Set<String> _noteIDs = new Set();
3231

3332
@override
3433
initState() {
3534
debugPrint("LoginPage");
3635
super.initState();
3736
_checkIfFirstTime();
38-
_loadIDsFromMemory(); // TODO remove?
37+
// _loadIDsFromMemory(); // TODO remove?
3938
}
4039

4140
void _checkIfFirstTime() async {
@@ -55,10 +54,11 @@ class _LoginPageState extends State<LoginPage> {
5554
}
5655
}
5756

58-
void _loadIDsFromMemory() async {
59-
SharedPreferences prefs = await SharedPreferences.getInstance();
60-
setState( () => _noteIDs = new Set.from(prefs.getStringList("noteIDs")) ?? new Set());
61-
}
57+
// void _loadIDsFromMemory() async {
58+
// SharedPreferences prefs = await SharedPreferences.getInstance();
59+
// setState( () => _noteIDs = new Set.from(prefs.getStringList("noteIDs")) ?? new Set());
60+
// debugPrint(_noteIDs.toString());
61+
// }
6262

6363
@override
6464
Widget build(BuildContext context) {
@@ -125,74 +125,96 @@ class _LoginPageState extends State<LoginPage> {
125125

126126
void _performLogin() async {
127127
// USER FEEDBACK: WE'RE DOING STUFF FOR YOU
128-
setState((){
128+
debugPrint("lala");
129+
130+
setState(() {
129131
_keyIconColor = Colors.amber;
130132
_errorMessage = "\n Verifying password. Please wait.";
131-
} );
133+
});
132134

133-
debugPrint("OK!!!!!!!!!!");
135+
authenticate();
136+
}
134137

135-
// === AUTHENTICATION FIRST ===
136-
String _passwordHash;
138+
void authenticate() async {
139+
// === AUTHENTICATION FIRST ===
140+
// If the user can authenticate, the same password will be used
141+
// To decrypt the note titles, and eventually the notes themselves
142+
// The password will be pushed to the note editor.
137143

138-
try { // fetch password hash from secure memory
139-
_passwordHash = await _secureStorage.read(key: "passwordHash");
140-
}
141-
catch (e) { // don't have a password yet -> make one
142-
setState(() {
143-
_errorMessage = "\n Securely storing new password. Please wait.";
144-
});
145-
Crypt newHashMachine = new Crypt.sha256(_userSuppliedPassword); // randomly salted (handled by Crypt)
146-
_passwordHash = newHashMachine.toString();
147-
await _secureStorage.write(key: "passwordHash", value: _passwordHash); // store password hash
148-
}
149-
if (_passwordHash == null) { // duplicate code sucks :(
150-
setState(() {
151-
_errorMessage = "\n Securely storing new password. Please wait.";
152-
});
153-
Crypt newHashMachine = new Crypt.sha256(_userSuppliedPassword); // randomly salted (handled by Crypt)
154-
_passwordHash = newHashMachine.toString();
155-
await _secureStorage.write(key: "passwordHash", value: _passwordHash); // store password hash
156-
}
144+
String _passwordHash;
157145

158-
Crypt hashMachine = new Crypt(_passwordHash);
159-
if (!hashMachine.match(_userSuppliedPassword)) { // Wrong password
160-
debugPrint(":( oo");
161-
setState((){
162-
_keyIconColor = Colors.red;
163-
_errorMessage = "\n Wrong password. Please retry.";
164-
});
146+
debugPrint("entertainers");
147+
148+
void onHashFetchFail() async {
149+
// first declare inner function
150+
setState(() {
151+
_errorMessage = "\n Securely storing new password. Please wait.";
152+
});
153+
Crypt newHashMachine = new Crypt.sha256(
154+
_userSuppliedPassword); // randomly salted (handled by Crypt)
155+
_passwordHash = newHashMachine.toString();
156+
await _secureStorage.write(
157+
key: "passwordHash", value: _passwordHash); // store password hash
158+
}
159+
try { // fetch password hash from secure memory
160+
_passwordHash = await _secureStorage.read(key: "passwordHash");
161+
}
162+
catch (e) { // don't have a password yet -> make one
163+
onHashFetchFail();
164+
}
165+
if (_passwordHash == null) {
166+
onHashFetchFail();
167+
}
168+
169+
Crypt hashMachine = new Crypt(_passwordHash);
170+
if (!hashMachine.match(_userSuppliedPassword)) { // Wrong password
171+
setState(() {
172+
_keyIconColor = Colors.red;
173+
_errorMessage = "\n Wrong password. Please retry.";
174+
});
175+
}
176+
else { // Correct password
177+
setState(() {
178+
_keyIconColor = Colors.greenAccent;
179+
_errorMessage = "\n Correct password. Decrypting. Please wait.";
180+
});
181+
// === LOGIN SUCCESSFUL -> DECRYPT NOTE TITLES ===
182+
decryptNoteTitles();
183+
}
184+
185+
debugPrint("hurroo");
165186
}
166-
else { // Correct password
167-
setState((){
168-
_keyIconColor = Colors.greenAccent;
169-
_errorMessage = "\n Correct password. Decrypting. Please wait.";
170-
});
171-
// === LOGIN SUCCESFUL -> DECRYPT NOTE TITLES ===
187+
188+
void decryptNoteTitles() async {
172189
final PlatformStringCryptor cryptor = new PlatformStringCryptor();
173190
debugPrint("crrct");
174191

192+
// _saltForNotes fetching or generating
175193
String _saltForNotes;
194+
void onSaltFetchFail() async {
195+
_saltForNotes = await cryptor.generateSalt();
196+
await _secureStorage.write(key: "saltForNotes", value: _saltForNotes);
197+
}
176198
try { // fetch salt from secure memory
177199
debugPrint("here");
178200
_saltForNotes = await _secureStorage.read(key: "saltForNotes");
179201
}
180202
catch (e) { // don't have a salt yet -> make one
181203
debugPrint("never");
182-
_saltForNotes = await cryptor.generateSalt();
183-
await _secureStorage.write(key: "saltForNotes", value: _saltForNotes);
204+
onSaltFetchFail();
184205
}
185206
if (_saltForNotes == null) {
186207
debugPrint("here!");
187-
_saltForNotes = _randomString(16); // 16 characters (should be bytes) salt
188-
await _secureStorage.write(key: "saltForNotes", value: _saltForNotes);
208+
onSaltFetchFail();
189209
}
210+
debugPrint("nice");
190211

191-
final String _key = await cryptor.generateKeyFromPassword("p", _saltForNotes); // TODO p
192-
193-
final String string = "Note titles fetched from memory:title 1:title 2:title 3"; // TODO validate titles (no ":")
212+
final String _key = await cryptor.generateKeyFromPassword("p", _saltForNotes);
213+
debugPrint("nice!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
214+
final String string = "Note titles fetched from memory\$title 1\$title 2\$title 3"; // TODO validate titles (no "$")
194215
final String encrypted = await cryptor.encrypt(string, _key);
195-
String _userSuppliedKey = await cryptor.generateKeyFromPassword(_userSuppliedPassword, _saltForNotes);
216+
//String _userSuppliedKey = await cryptor.generateKeyFromPassword(_userSuppliedPassword, _saltForNotes);
217+
final String _userSuppliedKey = await cryptor.generateKeyFromPassword(_userSuppliedPassword, _saltForNotes);
196218
String _noteTitlesDecrypted;
197219
try {
198220
_noteTitlesDecrypted = await cryptor.decrypt(encrypted, _userSuppliedKey);
@@ -207,29 +229,13 @@ class _LoginPageState extends State<LoginPage> {
207229
if (_noteTitlesDecrypted != null) {
208230
// doesn't matter if hacker sets this to non-null somehow, values aren't decrypted in that case :)
209231
Navigator.of(context).pushNamed('/homePage/$_key/$_noteTitlesDecrypted'); // TODO: slash probably not best option
210-
// TODO: use question mark or somethin :)
232+
// TODO: use question mark or somethin :) convert to base64?
211233
setState(() { _errorMessage = "\n ";});
212234
// TODO pass decrypted note titles to homepage
213235
}
214236

215237
}
216238

217-
debugPrint("hurroo");
218-
219-
}
220-
221-
String _randomString(int length) {
222-
var rand = new Random.secure();
223-
var codeUnits = new List.generate(
224-
length,
225-
(index){
226-
return rand.nextInt(33)+89;
227-
}
228-
);
229-
230-
return new String.fromCharCodes(codeUnits);
231-
}
232-
233239

234240

235241
}

pubspec.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ packages:
9191
name: cupertino_icons
9292
url: "https://pub.dartlang.org"
9393
source: hosted
94-
version: "0.1.1"
94+
version: "0.1.2"
9595
flutter:
9696
dependency: "direct main"
9797
description: flutter
@@ -110,7 +110,7 @@ packages:
110110
name: flutter_string_encryption
111111
url: "https://pub.dartlang.org"
112112
source: hosted
113-
version: "0.0.1"
113+
version: "0.0.2"
114114
flutter_test:
115115
dependency: "direct dev"
116116
description: flutter
@@ -290,7 +290,7 @@ packages:
290290
name: shared_preferences
291291
url: "https://pub.dartlang.org"
292292
source: hosted
293-
version: "0.4.0"
293+
version: "0.4.1"
294294
shelf:
295295
dependency: transitive
296296
description:

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ dependencies:
66
sdk: flutter
77
shared_preferences: # for the IDs (might become unnecessary)
88
path_provider: "^0.4.0" # to store the notes as files
9-
flutter_string_encryption: "^0.0.1" # to encrypt and decrypt the notes
9+
flutter_string_encryption: "^0.0.2" # to encrypt and decrypt the notes
1010
flutter_secure_storage: "^2.0.0" # to store the salt generated with flutter_string_encryption and the hashed passwd
1111
crypt: "^1.0.5" # to securely store the hashed and salted password
1212

0 commit comments

Comments
 (0)