🛡️ Dart Secure 🛡️
A Dart package that provides functionalities to enhance user authentication and data encryption in Dart applications. This package integrates multiple cybersecurity practices to secure sensitive user data and interactions. The package includes the following features:
Features
🔐 Temporary Lock User
🔑 User Authentication Monitoring
✋ Biometric User Authentication
🔒 InApp Data Encryption
🔓 InApp Data Decryption
🔐 Symmetric Encryption & Decryption
#️⃣ Hashing Data
✅ Client Validation
📖 Getting Started
To use this package, add dart_secure as a dependency in your pubspec.yaml file:
dependencies:
dart_secure: ^(check current version)
Then import the necessary features in your Dart code:
import 'package:dart_secure/dart_secure.dart';
Features
🔐 Temporary Lock User
You can use the tempLockUser method to lock the user after multiple failed login attempts. This function takes the following parameters:
context(required): TheBuildContextof the current screen.time(optional): The duration in seconds for which the user will be locked. Default is 30 seconds.afterCountNavigateTo(required): The widget to navigate to after the countdown timer finishes.lockedPageMessage(optional): The message to display on the locked user page. Default is "You are temporarily locked."
Future<void> lockUser() async {
await tempLockUser(
context,
time: 60, // Lock user for 60 seconds
afterCountNavigateTo: HomeScreen(), // Navigate to HomeScreen after timer finishes
lockedPageMessage: "Your account has been temporarily locked for security reasons.",
);
}
Customization
You can customize the appearance of the countdown timer page by modifying the _countdownPage function. This function creates the UI displayed to the user during the lockout period.
Note
- The package uses a
StreamBuilderto display the countdown timer and navigate to the next page once the timer completes. - The countdown timer can't be bypassed by pressing the back button.
Example
Here's a simple example of how to use the feature:
//Temporary lock the user
void TempLockThisUser() {
// Simulate a failed login attempt
tempLockUser(context, afterCountNavigateTo: LoginPage());
}
🔑 User Authentication Monitoring for Firebase
The userAuthMonitor feature allows you to monitor user authentication using Firebase Auth and display different pages based on the user's authentication state. This can be particularly useful for managing user access and providing a seamless experience for authenticated and unauthenticated users.
dependencies:
flutter:
sdk: flutter
firebase_auth: ^<latest_version>
Usage
To get started with user authentication monitoring, you can use the userAuthMonitor function provided by the dart_secure package. This function takes various parameters to customize the behavior based on your requirements:
authenticatedUserPage: The page/widget to be shown when the user is authenticated.unAuthenticatedUserPage: The page/widget to be shown when the user is not authenticated.adminUID: The UID of the admin user (optional). If provided, a specific admin page can be shown.adminPage: The page/widget to be shown if the authenticated user's UID matches theadminUID.blockUID: A list of UIDs representing blocked users (optional). Blocked users will see theuserBlockedPage.userBlockedPage: The page/widget to be shown for blocked users.
Here's an example of how you can use this feature:
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:dart_secure/dart_secure.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: userAuthMonitor(
authenticatedUserPage: HomePage(),
unAuthenticatedUserPage: LoginPage(),
adminUID: 'your_admin_uid_here',
adminPage: AdminPage(),
blockUID: ['blocked_user_uid_1', 'blocked_user_uid_2'],
userBlockedPage: UserBlockedPage(),
),
);
}
}
// Define your pages/widgets here (HomePage, LoginPage, AdminPage, UserBlockedPage).
This example demonstrates how to create a seamless user authentication experience with custom pages for different user states. Make sure to replace placeholder values with your actual implementation.
This new section provides an explanation of the new feature, its installation, usage, and a sample code snippet for integrating it into your Flutter application. Make sure to adjust the placeholders and example code to fit your actual implementation and requirements.
🧑✋ Biometric User Authentication
Note that this plugin works with both Touch ID and Face ID. However, to use Face ID, you need to add the following to your Info.plist file:
iOS Integration
<key>NSFaceIDUsageDescription</key>
<string>Why is my app authenticating using Face ID?</string>
Android Integration
- The plugin will build and run on SDK 16+, but
isDeviceSupported()will return false before SDK 23 (Android 6.0).
Activity Changes
local_auth requires the use of a FragmentActivity instead of an Activity. To update your application:
If you are using FlutterActivity directly, change it to FlutterFragmentActivity in your AndroidManifest.xml.
If you are using a custom activity, update your MainActivity.java or MainActivity.kt to inherit from FlutterFragmentActivity.
Permissions
Update your project's AndroidManifest.xml file to include the USE_BIOMETRIC permission:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app">
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
</manifest>
The biometricAuth feature offers a secure way to implement biometric user authentication in your app. It supports various biometric authentication methods on the device. Example usage:
getBiometric() async {
var authStatus = await biometricAuth();
if (authStatus == AuthenticationStatus.successful) {
print("Authentication successful, continue");
} else {
print("Authentication unsuccessful, try again");
}
}
🔒 In-App Encryption
The InAppEncryption feature allows you to encrypt sensitive data within your app using a specified encryption key:
String encryptedAddress = inAppEncrypt(text: "User's Address", key: "MyUsersAddress");
🔐 Symmetric Encryption
Use the symmetricEncrypt method to securely encrypt sensitive data using a 16-character symmetric key:
final encrypted = symmetricEncrypt(
text: 'Sensitive Information', // The text to encrypt
keyIV: '1234567890123456', // Exactly 16-character key
);
print('Encrypted Data: $encrypted');
#️⃣ Hash Encryption
The hashEncrypt feature securely hashes data with a salt, useful for scenarios like password storage:
String hashedAddress = hashEncrypt(
plainText: "User's Address",
keyIV: "MySaltKey1234567", // Salt value
);
🔓 In-App Decryption
The InAppDecryption feature lets you decrypt encrypted data within your app using the appropriate decryption key:
String encryptedAddress = InAppDecryption(cipher: "######################", key: "MyUsersAddress");
🔓 Symmetric Decryption
Use the symmetricDecryption method to decrypt data encrypted with symmetricEncrypt:
final decrypted = symmetricDecryption(
cipherText: 'NjY4ODZ3ZGJka2NzODg=', // Encrypted text
key: '1234567890123456', // Same 16-character key used to encrypt
);
print('Decrypted Data: $decrypted');
✅ Client Validation
The ClientValidator class provides a method to validate clients against a backend server and includes a UI page to inform users if the server is down.
Usage
To use the client validation feature:
-
Set the Backend Base URL: Before calling
validateClient, configure your backend's base URL usingClientValidator.setBackendBaseUrl(). The client ID will be appended to this URL.import 'package:dart_secure/dart_secure.dart'; // In your app's initialization (e.g., main() or initState of your main widget) ClientValidator.setBackendBaseUrl('https://vapp.alaqsa.tech/validate-app/'); -
Validate the Client: Call
ClientValidator.validateClient()with the client's ID.import 'package:dart_secure/dart_secure.dart'; Future<void> checkClientValidation(String clientId) async { bool isValid = await ClientValidator.validateClient(clientId); if (isValid) { // Client is valid, or server is unreachable/error. // You might need more sophisticated error handling in validateClient // to distinguish between 'server returned true' and 'server error'. print('Client $clientId is valid or server is down/error.'); } else { // Client is explicitly not valid (server returned false). print('Client $clientId is not valid. App access blocked.'); // Navigate to an unauthorized access page or block app usage. } }
Server Down Page
The package also includes a ServerDownPage widget that you can use to display a user-friendly message when your application cannot reach the backend server.
import 'package:flutter/material.dart';
import 'package:dart_secure/ui/server_down_page.dart';
// Example of navigating to the ServerDownPage
void navigateToServerDown(BuildContext context) {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const ServerDownPage()),
);
}
Release Notes
Version 2.0.0
- Upgraded package dependencies to latest major versions (
local_auth ^3.0.1,firebase_auth ^6.5.3,firebase_core ^4.11.0,crypto ^3.0.7). - Updated minimum SDK requirements to Dart 3.7.0 and Flutter 3.29.0.
- Fixed
symmetricEncryptandsymmetricDecryptionmismatch by implementing Salsa20 decryption. - Optimized countdown timer stream in
tempLockUserto remove the initial 1-second delay. - Fixed typo in validation client filename (
validate_client.dart) and implementation, and exported it from the main entry point. - Exposed
CheckFirebaseAuthenticationpublic widget and fixed missing type annotations.
Version 0.6.6
- Fixed missing type annotations, replaced deprecated
WillPopScopewithPopScope. - Fixed all example code errors and updated dependency constraints.
Version 0.6.5
- Fixed hidden bugs.
- Included new symmetric encryption and decryption methods.
Version 0.6.0
- Added
ClientValidatorclass andServerDownPageUI widget.
Version 0.5.0
- Included a new Temporary Lock User feature.
Version 0.4.0
- Added User Authentication Monitoring with examples.
Version 0.3.0
- Added illustrative examples for improved understanding and clarity.
Version 0.2.0
- Enhanced Biometric documentation.
Version 0.1.0
- Initial release of the Dart Secure framework.
For more details and information about the package usage, refer to the GitHub repository.
If you encounter issues or have improvement suggestions, open an issue on GitHub.
🌻 License
This project is open-source software licensed under the MIT License.
💙 Support the Development of the Dart Secure Project 💙
Created with ❤️ by SaifAlmajd