mirror of
https://github.com/mitchell/selfpass.git
synced 2025-12-14 21:27:22 +00:00
Add aes-cbc encryption; add config repo based on shared_preferences
This commit is contained in:
parent
80f9705b19
commit
67744527cc
15 changed files with 254 additions and 154 deletions
25
client/lib/repositories/config_base.dart
Normal file
25
client/lib/repositories/config_base.dart
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
class ConfigBase {
|
||||
static const keyPrivateKey = "private_key";
|
||||
static const keyConnectionConfig = "connection_config";
|
||||
static const keyPassword = "password";
|
||||
|
||||
bool passwordMatched = false;
|
||||
String _password;
|
||||
|
||||
String get password {
|
||||
checkIfPasswordMatched();
|
||||
return _password;
|
||||
}
|
||||
|
||||
set password(String password) => _password = password;
|
||||
|
||||
void checkIfPasswordMatched() {
|
||||
if (passwordMatched) return;
|
||||
throw Exception('password not matched yet');
|
||||
}
|
||||
|
||||
void reset() {
|
||||
passwordMatched = false;
|
||||
_password = null;
|
||||
}
|
||||
}
|
||||
102
client/lib/repositories/encrypted_shared_preferences.dart
Normal file
102
client/lib/repositories/encrypted_shared_preferences.dart
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'config_base.dart';
|
||||
|
||||
import '../types/abstracts.dart';
|
||||
import '../types/connection_config.dart';
|
||||
|
||||
import '../utils/crypto.dart' as crypto;
|
||||
|
||||
class EncryptedSharedPreferences extends ConfigBase implements ConfigRepo {
|
||||
@override
|
||||
Future<ConnectionConfig> get connectionConfig async {
|
||||
checkIfPasswordMatched();
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final cipherText = prefs.getString(ConfigBase.keyConnectionConfig);
|
||||
|
||||
if (cipherText == null) return null;
|
||||
|
||||
final configJson = crypto.decrypt(cipherText, password);
|
||||
|
||||
return ConnectionConfig.fromJson(json.decode(configJson));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteAll() async {
|
||||
checkIfPasswordMatched();
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
prefs.remove(ConfigBase.keyConnectionConfig);
|
||||
prefs.remove(ConfigBase.keyPassword);
|
||||
prefs.remove(ConfigBase.keyPrivateKey);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> matchesPasswordHash(String password) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
passwordMatched = crypto.matchHashedPassword(
|
||||
prefs.getString(ConfigBase.keyPassword),
|
||||
password,
|
||||
);
|
||||
|
||||
if (passwordMatched) this.password = password;
|
||||
|
||||
return passwordMatched;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> get passwordIsSet async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
final isSet = prefs.containsKey(ConfigBase.keyPassword);
|
||||
passwordMatched = !isSet;
|
||||
|
||||
return isSet;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> get privateKey async {
|
||||
checkIfPasswordMatched();
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final cipherText = prefs.getString(ConfigBase.keyPrivateKey);
|
||||
|
||||
return crypto.decrypt(cipherText, password);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setConnectionConfig(ConnectionConfig config) async {
|
||||
checkIfPasswordMatched();
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
final configJson = json.encode(config);
|
||||
|
||||
prefs.setString(
|
||||
ConfigBase.keyConnectionConfig,
|
||||
crypto.encrypt(configJson, password),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setPassword(String password) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
this.password = password;
|
||||
passwordMatched = true;
|
||||
|
||||
prefs.setString(ConfigBase.keyPassword, crypto.hashPassword(password));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setPrivateKey(String key) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
prefs.setString(ConfigBase.keyPrivateKey, crypto.encrypt(key, password));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
import '../types/abstracts.dart';
|
||||
import '../types/connection_config.dart';
|
||||
|
||||
import '../utils/crypto.dart' as crypto;
|
||||
|
||||
class SecureStorageConfig implements ConfigRepo {
|
||||
static const _keyPrivateKey = "private_key";
|
||||
static const _keyConnectionConfig = "connection_config";
|
||||
static const _keyPassword = "password";
|
||||
|
||||
final _storage = FlutterSecureStorage();
|
||||
|
||||
bool _passwordMatched = false;
|
||||
String _password;
|
||||
|
||||
String get password {
|
||||
_checkIfPasswordMatched();
|
||||
return _password;
|
||||
}
|
||||
|
||||
Future<void> setPrivateKey(String key) {
|
||||
_checkIfPasswordMatched();
|
||||
return _storage.write(key: _keyPrivateKey, value: key.replaceAll('-', ''));
|
||||
}
|
||||
|
||||
Future<String> get privateKey {
|
||||
_checkIfPasswordMatched();
|
||||
return _storage.read(key: _keyPrivateKey);
|
||||
}
|
||||
|
||||
Future<void> setPassword(String password) {
|
||||
_checkIfPasswordMatched();
|
||||
|
||||
_password = password;
|
||||
|
||||
return _storage.write(
|
||||
key: _keyPassword, value: crypto.hashPassword(password));
|
||||
}
|
||||
|
||||
Future<bool> get passwordIsSet async {
|
||||
final passHash = await _storage.read(key: _keyPassword);
|
||||
|
||||
if (passHash != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_passwordMatched = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Future<bool> matchesPasswordHash(String password) async {
|
||||
_passwordMatched = crypto.matchHashedPassword(
|
||||
await _storage.read(key: _keyPassword), password);
|
||||
|
||||
if (_passwordMatched) _password = password;
|
||||
|
||||
return _passwordMatched;
|
||||
}
|
||||
|
||||
Future<void> setConnectionConfig(ConnectionConfig config) {
|
||||
_checkIfPasswordMatched();
|
||||
return _storage.write(
|
||||
key: _keyConnectionConfig, value: json.encode(config));
|
||||
}
|
||||
|
||||
Future<ConnectionConfig> get connectionConfig async {
|
||||
_checkIfPasswordMatched();
|
||||
final connConfig = await _storage.read(key: _keyConnectionConfig);
|
||||
|
||||
if (connConfig == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ConnectionConfig.fromJson(json.decode(connConfig));
|
||||
}
|
||||
|
||||
Future<void> deleteAll() {
|
||||
_checkIfPasswordMatched();
|
||||
return _storage.deleteAll();
|
||||
}
|
||||
|
||||
void _checkIfPasswordMatched() {
|
||||
if (_passwordMatched) return;
|
||||
throw Exception('password not matched yet');
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue