[mob][auth] Implemented Pin/Password hashing using ente_crypto

This commit is contained in:
Aman Raj Singh Mourya
2024-07-12 15:58:23 +05:30
parent d06586eb1c
commit fb0d938cb5
10 changed files with 233 additions and 140 deletions

View File

@@ -0,0 +1,14 @@
import "package:ente_auth/events/event.dart";
enum AppLockUpdateType {
none,
device,
pin,
password,
}
class AppLockUpdateEvent extends Event {
final AppLockUpdateType type;
AppLockUpdateEvent(this.type);
}

View File

@@ -25,7 +25,11 @@ class LocalAuthenticationService {
) async {
if (await _isLocalAuthSupportedOnDevice()) {
AppLock.of(context)!.setEnabled(false);
final result = await requestAuthentication(context, infoMessage);
final result = await requestAuthentication(
context,
infoMessage,
isAuthenticatingForInAppChange: true,
);
AppLock.of(context)!.setEnabled(
await Configuration.instance.shouldShowLockScreen(),
);
@@ -43,15 +47,17 @@ class LocalAuthenticationService {
BuildContext context,
String? savedPin,
String? savedPassword, {
bool isOnOpeningApp = false,
bool isAuthenticatingOnAppLaunch = false,
bool isAuthenticatingForInAppChange = false,
}) async {
if (savedPassword != null) {
final result = await Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return LockScreenPassword(
isAuthenticating: true,
isOnOpeningApp: isOnOpeningApp,
isChangingLockScreenSettings: true,
isAuthenticatingForInAppChange: isAuthenticatingForInAppChange,
isAuthenticatingOnAppLaunch: isAuthenticatingOnAppLaunch,
authPass: savedPassword,
);
},
@@ -66,8 +72,9 @@ class LocalAuthenticationService {
MaterialPageRoute(
builder: (BuildContext context) {
return LockScreenPin(
isAuthenticating: true,
isOnOpeningApp: isOnOpeningApp,
isChangingLockScreenSettings: true,
isAuthenticatingForInAppChange: isAuthenticatingForInAppChange,
isAuthenticatingOnAppLaunch: isAuthenticatingOnAppLaunch,
authPin: savedPin,
);
},

View File

@@ -10,7 +10,6 @@ class CustomPinKeypad extends StatelessWidget {
return SafeArea(
child: Container(
padding: const EdgeInsets.all(2),
// color: getEnteColorScheme(context).strokeFainter,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [

View File

@@ -71,22 +71,13 @@ class _LockScreenConfirmPinState extends State<LockScreenConfirmPin> {
),
floatingActionButton: CustomPinKeypad(controller: _confirmPinController),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
// body: OrientationBuilder(
// builder: (context, orientation) {
// return orientation == Orientation.portrait
// ? _getBody(colorTheme, textTheme, isPortrait: true)
// : SingleChildScrollView(
// child: _getBody(colorTheme, textTheme, isPortrait: false),
// );
// },
// ),
body: SingleChildScrollView(
child: _getBody(colorTheme, textTheme, isPortrait: true),
child: _getBody(colorTheme, textTheme),
),
);
}
Widget _getBody(colorTheme, textTheme, {required bool isPortrait}) {
Widget _getBody(colorTheme, textTheme) {
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
@@ -200,10 +191,6 @@ class _LockScreenConfirmPinState extends State<LockScreenConfirmPin> {
await _confirmPinMatch();
},
),
// isPortrait
// ? const Spacer()
// : const Padding(padding: EdgeInsets.all(12)),
// CustomPinKeypad(controller: _confirmPinController),
],
),
);

View File

@@ -1,6 +1,8 @@
import "dart:async";
import "package:ente_auth/core/configuration.dart";
import "package:ente_auth/core/event_bus.dart";
import "package:ente_auth/events/app_lock_update_event.dart";
import "package:ente_auth/theme/ente_theme.dart";
import "package:ente_auth/ui/components/captioned_text_widget.dart";
import "package:ente_auth/ui/components/divider_widget.dart";
@@ -29,15 +31,11 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
late bool appLock;
bool isPinEnabled = false;
bool isPasswordEnabled = false;
late String autoLockTime;
late int autoLockTimeInMilliseconds;
@override
void initState() {
super.initState();
autoLockTime = _formatTime(
Duration(
milliseconds: _lockscreenSetting.getAutoLockTime(),
),
);
autoLockTimeInMilliseconds = _lockscreenSetting.getAutoLockTime();
_initializeSettings();
appLock = isPinEnabled ||
isPasswordEnabled ||
@@ -56,6 +54,12 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
Future<void> _deviceLock() async {
await _lockscreenSetting.removePinAndPassword();
await _initializeSettings();
await _lockscreenSetting.setAppLockType("Device lock");
Bus.instance.fire(
AppLockUpdateEvent(
AppLockUpdateType.device,
),
);
}
Future<void> _pinLock() async {
@@ -69,6 +73,12 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
setState(() {
_initializeSettings();
if (result) {
Bus.instance.fire(
AppLockUpdateEvent(
AppLockUpdateType.pin,
),
);
_lockscreenSetting.setAppLockType("Pin");
appLock = isPinEnabled ||
isPasswordEnabled ||
_configuration.shouldShowSystemLockScreen();
@@ -87,6 +97,12 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
setState(() {
_initializeSettings();
if (result) {
Bus.instance.fire(
AppLockUpdateEvent(
AppLockUpdateType.password,
),
);
_lockscreenSetting.setAppLockType("Password");
appLock = isPinEnabled ||
isPasswordEnabled ||
_configuration.shouldShowSystemLockScreen();
@@ -98,6 +114,12 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
AppLock.of(context)!.setEnabled(!appLock);
await _configuration.setSystemLockScreen(!appLock);
await _lockscreenSetting.removePinAndPassword();
await _lockscreenSetting.setAppLockType(appLock ? "None" : "Device lock");
Bus.instance.fire(
AppLockUpdateEvent(
appLock ? AppLockUpdateType.none : AppLockUpdateType.device,
),
);
setState(() {
_initializeSettings();
appLock = !appLock;
@@ -111,11 +133,7 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
).then(
(value) {
setState(() {
autoLockTime = _formatTime(
Duration(
milliseconds: _lockscreenSetting.getAutoLockTime(),
),
);
autoLockTimeInMilliseconds = _lockscreenSetting.getAutoLockTime();
});
},
);
@@ -123,11 +141,11 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
String _formatTime(Duration duration) {
if (duration.inHours != 0) {
return "${duration.inHours}hr";
return "in ${duration.inHours} hour${duration.inHours > 1 ? 's' : ''}";
} else if (duration.inMinutes != 0) {
return "${duration.inMinutes}m";
return "in ${duration.inMinutes} minute${duration.inMinutes > 1 ? 's' : ''}";
} else if (duration.inSeconds != 0) {
return "${duration.inSeconds}s";
return "in ${duration.inSeconds} second${duration.inSeconds > 1 ? 's' : ''}";
} else {
return "Disable";
}
@@ -191,6 +209,7 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
),
appLock
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MenuItemWidget(
captionedTextWidget:
@@ -249,14 +268,32 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
),
MenuItemWidget(
captionedTextWidget: CaptionedTextWidget(
title: "Auto-lock",
subTitle: autoLockTime,
title: "Auto lock",
subTitle: _formatTime(
Duration(
milliseconds:
autoLockTimeInMilliseconds,
),
),
),
singleBorderRadius: 8,
alignCaptionedTextToLeft: true,
singleBorderRadius: 8,
menuItemColor: colorTheme.fillFaint,
trailingIconColor: colorTheme.textBase,
onTap: () => _onAutoLock(),
),
Padding(
padding: const EdgeInsets.only(
top: 14,
left: 14,
right: 12,
),
child: Text(
"Require ${_lockscreenSetting.getAppLockType()} if away for some time .",
style: textTheme.miniFaint,
textAlign: TextAlign.left,
),
),
],
)
: Container(),

View File

@@ -1,3 +1,5 @@
import "dart:convert";
import "package:ente_auth/theme/ente_theme.dart";
import "package:ente_auth/ui/common/dynamic_fab.dart";
import "package:ente_auth/ui/components/buttons/icon_button_widget.dart";
@@ -5,20 +7,32 @@ import "package:ente_auth/ui/components/text_input_widget.dart";
import "package:ente_auth/ui/settings/lock_screen/lock_screen_confirm_password.dart";
import "package:ente_auth/ui/settings/lock_screen/lock_screen_options.dart";
import "package:ente_auth/utils/lock_screen_settings.dart";
import "package:ente_crypto_dart/ente_crypto_dart.dart";
import "package:flutter/material.dart";
import "package:flutter/services.dart";
/// [isChangingLockScreenSettings] Authentication required for changing lock screen settings.
/// Set to true when the app requires the user to authenticate before allowing
/// changes to the lock screen settings.
/// [isAuthenticatingOnAppLaunch] Authentication required on app launch.
/// Set to true when the app requires the user to authenticate immediately upon opening.
/// [isAuthenticatingForInAppChange] Authentication required for in-app changes (e.g., email, password).
/// Set to true when the app requires the to authenticate for sensitive actions like email, password changes.
class LockScreenPassword extends StatefulWidget {
const LockScreenPassword({
super.key,
this.isAuthenticating = false,
this.isOnOpeningApp = false,
this.isChangingLockScreenSettings = false,
this.isAuthenticatingOnAppLaunch = false,
this.isAuthenticatingForInAppChange = false,
this.authPass,
});
//Is false when setting a new password
final bool isAuthenticating;
final bool isOnOpeningApp;
final bool isChangingLockScreenSettings;
final bool isAuthenticatingOnAppLaunch;
final bool isAuthenticatingForInAppChange;
final String? authPass;
@override
State<LockScreenPassword> createState() => _LockScreenPasswordState();
@@ -149,7 +163,9 @@ class _LockScreenPasswordState extends State<LockScreenPassword> {
),
),
Text(
widget.isAuthenticating ? "Enter Password" : "Set new Password",
widget.isChangingLockScreenSettings
? "Enter Password"
: "Set new Password",
textAlign: TextAlign.center,
style: textTheme.bodyBold,
),
@@ -181,17 +197,19 @@ class _LockScreenPasswordState extends State<LockScreenPassword> {
}
Future<bool> _confirmPasswordAuth(String inputtedPassword) async {
// final Uint8List? salt = await _lockscreenSetting.getSalt();
// final hash = cryptoPwHash({
// "password": utf8.encode(inputtedPassword),
// "salt": salt,
// "opsLimit": Sodium.cryptoPwhashOpslimitInteractive,
// "memLimit": Sodium.cryptoPwhashMemlimitInteractive,
// });
if (widget.authPass == inputtedPassword) {
final Uint8List? salt = await _lockscreenSetting.getSalt();
final hash = cryptoPwHash(
utf8.encode(inputtedPassword),
salt!,
sodium.crypto.pwhash.memLimitSensitive,
sodium.crypto.pwhash.opsLimitSensitive,
sodium,
);
if (widget.authPass == base64Encode(hash)) {
await _lockscreenSetting.setInvalidAttemptCount(0);
widget.isOnOpeningApp
widget.isAuthenticatingOnAppLaunch ||
widget.isAuthenticatingForInAppChange
? Navigator.of(context).pop(true)
: Navigator.of(context).pushReplacement(
MaterialPageRoute(
@@ -200,7 +218,7 @@ class _LockScreenPasswordState extends State<LockScreenPassword> {
);
return true;
} else {
if (widget.isOnOpeningApp) {
if (widget.isAuthenticatingOnAppLaunch) {
invalidAttemptsCount++;
await _lockscreenSetting.setInvalidAttemptCount(invalidAttemptsCount);
if (invalidAttemptsCount > 4) {
@@ -214,7 +232,7 @@ class _LockScreenPasswordState extends State<LockScreenPassword> {
}
Future<void> _confirmPassword() async {
if (widget.isAuthenticating) {
if (widget.isChangingLockScreenSettings) {
await _confirmPasswordAuth(_passwordController.text);
return;
} else {

View File

@@ -1,3 +1,5 @@
import "dart:convert";
import "package:ente_auth/theme/colors.dart";
import "package:ente_auth/theme/ente_theme.dart";
import "package:ente_auth/theme/text_style.dart";
@@ -5,21 +7,33 @@ import "package:ente_auth/ui/settings/lock_screen/custom_pin_keypad.dart";
import "package:ente_auth/ui/settings/lock_screen/lock_screen_confirm_pin.dart";
import "package:ente_auth/ui/settings/lock_screen/lock_screen_options.dart";
import "package:ente_auth/utils/lock_screen_settings.dart";
import "package:ente_crypto_dart/ente_crypto_dart.dart";
import "package:flutter/material.dart";
import "package:flutter/services.dart";
import 'package:pinput/pinput.dart';
/// [isChangingLockScreenSettings] Authentication required for changing lock screen settings.
/// Set to true when the app requires the user to authenticate before allowing
/// changes to the lock screen settings.
/// [isAuthenticatingOnAppLaunch] Authentication required on app launch.
/// Set to true when the app requires the user to authenticate immediately upon opening.
/// [isAuthenticatingForInAppChange] Authentication required for in-app changes (e.g., email, password).
/// Set to true when the app requires the to authenticate for sensitive actions like email, password changes.
class LockScreenPin extends StatefulWidget {
const LockScreenPin({
super.key,
this.isAuthenticating = false,
this.isOnOpeningApp = false,
this.isChangingLockScreenSettings = false,
this.isAuthenticatingOnAppLaunch = false,
this.isAuthenticatingForInAppChange = false,
this.authPin,
});
//Is false when setting a new password
final bool isAuthenticating;
final bool isOnOpeningApp;
final bool isAuthenticatingOnAppLaunch;
final bool isChangingLockScreenSettings;
final bool isAuthenticatingForInAppChange;
final String? authPin;
@override
State<LockScreenPin> createState() => _LockScreenPinState();
@@ -45,18 +59,19 @@ class _LockScreenPinState extends State<LockScreenPin> {
}
Future<bool> confirmPinAuth(String inputtedPin) async {
// final Uint8List? salt = await _lockscreenSetting.getSalt();
// final hash = cryptoPwHash({
// "password": utf8.encode(code),
// "salt": salt,
// "opsLimit": Sodium.cryptoPwhashOpslimitInteractive,
// "memLimit": Sodium.cryptoPwhashMemlimitInteractive,
// });
// final String hashedPin = base64Encode(hash);
if (widget.authPin == inputtedPin) {
final Uint8List? salt = await _lockscreenSetting.getSalt();
final hash = cryptoPwHash(
utf8.encode(inputtedPin),
salt!,
sodium.crypto.pwhash.memLimitSensitive,
sodium.crypto.pwhash.opsLimitSensitive,
sodium,
);
if (widget.authPin == base64Encode(hash)) {
invalidAttemptsCount = 0;
await _lockscreenSetting.setInvalidAttemptCount(0);
widget.isOnOpeningApp
widget.isAuthenticatingOnAppLaunch ||
widget.isAuthenticatingForInAppChange
? Navigator.of(context).pop(true)
: Navigator.of(context).pushReplacement(
MaterialPageRoute(
@@ -75,7 +90,7 @@ class _LockScreenPinState extends State<LockScreenPin> {
isPinValid = false;
});
if (widget.isOnOpeningApp) {
if (widget.isAuthenticatingOnAppLaunch) {
invalidAttemptsCount++;
await _lockscreenSetting.setInvalidAttemptCount(invalidAttemptsCount);
if (invalidAttemptsCount > 4) {
@@ -87,7 +102,7 @@ class _LockScreenPinState extends State<LockScreenPin> {
}
Future<void> _confirmPin(String inputtedPin) async {
if (widget.isAuthenticating) {
if (widget.isChangingLockScreenSettings) {
await confirmPinAuth(inputtedPin);
return;
} else {
@@ -130,26 +145,16 @@ class _LockScreenPinState extends State<LockScreenPin> {
),
floatingActionButton: CustomPinKeypad(controller: _pinController),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
// body: OrientationBuilder(
// builder: (context, orientation) {
// return orientation == Orientation.portrait
// ? _getBody(colorTheme, textTheme, isPortrait: true)
// : SingleChildScrollView(
// child: _getBody(colorTheme, textTheme, isPortrait: false),
// );
// },
// ),
body: SingleChildScrollView(
child: _getBody(colorTheme, textTheme, isPortrait: true),
child: _getBody(colorTheme, textTheme),
),
);
}
Widget _getBody(
EnteColorScheme colorTheme,
EnteTextTheme textTheme, {
required bool isPortrait,
}) {
EnteTextTheme textTheme,
) {
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
@@ -219,7 +224,7 @@ class _LockScreenPinState extends State<LockScreenPin> {
),
),
Text(
widget.isAuthenticating ? "Enter PIN" : "Set new PIN",
widget.isChangingLockScreenSettings ? "Enter PIN" : "Set new PIN",
style: textTheme.bodyBold,
),
const Padding(padding: EdgeInsets.all(12)),
@@ -263,10 +268,6 @@ class _LockScreenPinState extends State<LockScreenPin> {
await _confirmPin(_pinController.text);
},
),
// isPortrait
// ? const Spacer()
// : const Padding(padding: EdgeInsets.all(12)),
// CustomPinKeypad(controller: _pinController),
],
),
);

View File

@@ -2,6 +2,8 @@ import 'dart:async';
import 'dart:typed_data';
import 'package:ente_auth/core/configuration.dart';
import 'package:ente_auth/core/event_bus.dart';
import 'package:ente_auth/events/app_lock_update_event.dart';
import 'package:ente_auth/l10n/l10n.dart';
import 'package:ente_auth/models/user_details.dart';
import 'package:ente_auth/services/local_authentication_service.dart';
@@ -18,6 +20,7 @@ import 'package:ente_auth/ui/settings/common_settings.dart';
import 'package:ente_auth/ui/settings/lock_screen/lock_screen_options.dart';
import 'package:ente_auth/utils/auth_util.dart';
import 'package:ente_auth/utils/dialog_util.dart';
import 'package:ente_auth/utils/lock_screen_settings.dart';
import 'package:ente_auth/utils/navigation_util.dart';
import 'package:ente_auth/utils/platform_util.dart';
import 'package:ente_auth/utils/toast_util.dart';
@@ -37,15 +40,25 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
final _config = Configuration.instance;
late bool _hasLoggedIn;
final Logger _logger = Logger('SecuritySectionWidget');
late String appLockSubtitle;
late StreamSubscription<AppLockUpdateEvent> _appLockUpdateEvent;
@override
void initState() {
_hasLoggedIn = _config.hasConfiguredAccount();
appLockSubtitle = LockScreenSettings.instance.getAppLockType();
_appLockUpdateEvent = Bus.instance.on<AppLockUpdateEvent>().listen((event) {
if (mounted) {
setState(() {
appLockSubtitle = LockScreenSettings.instance.getAppLockType();
});
}
});
super.initState();
}
@override
void dispose() {
_appLockUpdateEvent.cancel();
super.dispose();
}
@@ -137,8 +150,9 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
}
children.addAll([
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
captionedTextWidget: CaptionedTextWidget(
title: "App lock",
subTitle: appLockSubtitle,
),
trailingIcon: Icons.chevron_right_outlined,
trailingIconIsMuted: true,

View File

@@ -14,6 +14,7 @@ Future<bool> requestAuthentication(
BuildContext context,
String reason, {
bool isOpeningApp = false,
bool isAuthenticatingForInAppChange = false,
}) async {
Logger("AuthUtil").info("Requesting authentication");
@@ -25,7 +26,8 @@ Future<bool> requestAuthentication(
context,
savedPin,
savedPassword,
isOnOpeningApp: isOpeningApp,
isAuthenticatingOnAppLaunch: isOpeningApp,
isAuthenticatingForInAppChange: isAuthenticatingForInAppChange,
);
}
if (Platform.isMacOS || Platform.isLinux) {

View File

@@ -1,3 +1,8 @@
import "dart:convert";
import "dart:typed_data";
import "package:ente_crypto_dart/ente_crypto_dart.dart";
import "package:flutter_secure_storage/flutter_secure_storage.dart";
import "package:shared_preferences/shared_preferences.dart";
class LockScreenSettings {
@@ -11,6 +16,7 @@ class LockScreenSettings {
static const keyInvalidAttempts = "ls_invalid_attempts";
static const lastInvalidAttemptTime = "ls_last_invalid_attempt_time";
static const autoLockTime = "ls_auto_lock_time";
static const appLockType = "ls_app_lock_type";
final List<Duration> autoLockDurations = const [
Duration(seconds: 0),
Duration(seconds: 30),
@@ -22,11 +28,20 @@ class LockScreenSettings {
];
late SharedPreferences _preferences;
late FlutterSecureStorage _secureStorage;
Future<void> init() async {
_secureStorage = const FlutterSecureStorage();
_preferences = await SharedPreferences.getInstance();
}
Future<void> setAppLockType(String lockType) async {
await _preferences.setString(appLockType, lockType);
}
String getAppLockType() {
return _preferences.getString(appLockType) ?? "None";
}
Future<void> setAutoLockTime(Duration duration) async {
await _preferences.setInt(autoLockTime, duration.inMilliseconds);
}
@@ -51,86 +66,85 @@ class LockScreenSettings {
await _preferences.setInt(keyInvalidAttempts, count);
}
// static Uint8List _generateSalt() {
// return Sodium.randombytesBuf(Sodium.cryptoPwhashSaltbytes);
// }
static Uint8List _generateSalt() {
return sodium.randombytes.buf(sodium.crypto.pwhash.saltBytes);
}
Future<void> setPin(String userPin) async {
//await _secureStorage.delete(key: saltKey);
await _secureStorage.delete(key: saltKey);
await _preferences.setString(pin, userPin);
await _preferences.remove(password);
// final salt = _generateSalt();
// final hash = cryptoPwHash({
// "password": utf8.encode(userPin),
// "salt": salt,
// "opsLimit": Sodium.cryptoPwhashOpslimitInteractive,
// "memLimit": Sodium.cryptoPwhashMemlimitInteractive,
// });
final salt = _generateSalt();
// final String saltPin = base64Encode(salt);
// final String hashedPin = base64Encode(hash);
final hash = cryptoPwHash(
utf8.encode(userPin),
salt,
sodium.crypto.pwhash.memLimitSensitive,
sodium.crypto.pwhash.opsLimitSensitive,
sodium,
);
final String saltPin = base64Encode(salt);
final String hashedPin = base64Encode(hash);
// await _secureStorage.write(key: saltKey, value: saltPin);
// await _secureStorage.write(key: pin, value: hashedPin);
// await _secureStorage.delete(key: password);
await _secureStorage.write(key: saltKey, value: saltPin);
await _secureStorage.write(key: pin, value: hashedPin);
await _secureStorage.delete(key: password);
return;
}
// Future<Uint8List?> getSalt() async {
// final String? salt = await _secureStorage.read(key: saltKey);
// if (salt == null) return null;
// return base64Decode(salt);
// }
Future<Uint8List?> getSalt() async {
final String? salt = await _secureStorage.read(key: saltKey);
if (salt == null) return null;
return base64Decode(salt);
}
Future<String?> getPin() async {
return _preferences.getString(pin);
// return _secureStorage.read(key: pin);
return _secureStorage.read(key: pin);
}
Future<void> setPassword(String pass) async {
await _preferences.setString(password, pass);
await _preferences.remove(pin);
// await _secureStorage.delete(key: saltKey);
await _secureStorage.delete(key: saltKey);
// final salt = _generateSalt();
// final hash = cryptoPwHash({
// "password": utf8.encode(pass),
// "salt": salt,
// "opsLimit": Sodium.cryptoPwhashOpslimitInteractive,
// "memLimit": Sodium.cryptoPwhashMemlimitInteractive,
// });
final salt = _generateSalt();
// final String saltPassword = base64Encode(salt);
// final String hashPassword = base64Encode(hash);
final hash = cryptoPwHash(
utf8.encode(pass),
salt,
sodium.crypto.pwhash.memLimitSensitive,
sodium.crypto.pwhash.opsLimitSensitive,
sodium,
);
// await _secureStorage.write(key: saltKey, value: saltPassword);
// await _secureStorage.write(key: password, value: hashPassword);
// await _secureStorage.delete(key: pin);
final String saltPassword = base64Encode(salt);
final String hashPassword = base64Encode(hash);
await _secureStorage.write(key: saltKey, value: saltPassword);
await _secureStorage.write(key: password, value: hashPassword);
await _secureStorage.delete(key: pin);
return;
}
Future<String?> getPassword() async {
return _preferences.getString(password);
// return _secureStorage.read(key: password);
return _secureStorage.read(key: password);
}
Future<void> removePinAndPassword() async {
await _preferences.remove(pin);
await _preferences.remove(password);
// await _secureStorage.delete(key: saltKey);
// await _secureStorage.delete(key: pin);
// await _secureStorage.delete(key: password);
await _secureStorage.delete(key: saltKey);
await _secureStorage.delete(key: pin);
await _secureStorage.delete(key: password);
}
Future<bool> isPinSet() async {
return _preferences.containsKey(pin);
// return await _secureStorage.containsKey(key: pin);
return await _secureStorage.containsKey(key: pin);
}
Future<bool> isPasswordSet() async {
return _preferences.containsKey(password);
// return await _secureStorage.containsKey(key: password);
return await _secureStorage.containsKey(key: password);
}
}