Best way to encrypt data - encryption

I want to encrypt/decrypt my data using the encrypt package.
But the app takes long time to executing and displaying data to the UI. So I'm looking for a best way to improve my code.
I have created a model like that.
class Users{
String id;
String name;
String surname;
}
Users(
{this.id, this.name, this.surname});
Map<String, Object> toMap() => {
'id': id,
'name': encryptData(name, key),
'surname': encryptData(surname,key)
};
Users.fromMap(Map<String, dynamic> u) {
id = u['id'];
name= decryptData(u['name'], key);
surname= decryptData(u['surname'], key);
}
And I decrypt the data called each time I want to use it as well I encrypt it when I want to store it in the database.
I use the code below for the encryption
String decryptData(String field, List<int> strkey) {
try {
final key = Key.fromBase64(base64Encode(Uint8List.fromList(strkey)));
final iv = IV.fromUtf8('utf8_string');
final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
final decrypt= encrypter.decrypt(Encrypted.fromBase64(field.base64), iv: iv);
return decrypt;
} catch (Ex) {
print('DECRYPError===${Ex}');
return field;
}
}
String encryptData(String field, List<int> strkey) {
try {
final key = Key.fromBase64(base64Encode(Uint8List.fromList(strkey)));
final iv = IV.fromUtf8('utf8_string');
final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
final encrypted = encrypter.encrypt(field, iv: iv);
return encrypted.base64;
} catch (Ex) {
print('CRYPError===${Ex}');
return field;
}
}

Create one Data transfer object class in serialisation and transfer the data.
Create one DTO object the serialisation and deserialization will take care of encryption and decryption of data
Declare private data members and public setter and getter methods in that DTO class. Also parameterized constructor.

Related

fetching user data from firebase and storing it in static variables

i am new to flutter and firebase development, so i really don't know how much will it cost me to keep fetching user data from firebase in every screen that i need them in, so i decided to fetch them once and store them in class MyUser static variables as follows:
in MyApp class:
bool isAuthenticated = false;
Future checkAuthenticity() async {
AuthService.getCurrentUser().then((user) async {
if (user != null) {
String myUid = await AuthService.getCurrentUID();
await MyUserController().getCurrentUserFromFirebase(myUid);
if (mounted)
setState(() {
isAuthenticated = true;
});
} else {
if (mounted)
setState(() {
isAuthenticated = false;
});
}
});
}
#override
Widget build(BuildContext context) {
home: isAuthenticated ? Home(passedSelectedIndex: 0) : Register(),
}
from the above code, this line await MyUserController().getCurrentUserFromFirebase(myUid); is as follows:
getCurrentUserFromFirebase(String uid) async {
await FirestoreService().getCurrentUserData(uid);
}
from the above code, this line await FirestoreService().getCurrentUserData(uid); is as follows:
Future getCurrentUserData(String uid) async {
try {
var userData = await FirebaseFirestore.instance.collection('users').doc(uid).get();
MyUser.fromData(userData.data());
} catch (e) {
if (e is PlatformException) {
return e.message;
}
return e.toString();
}
}
from the above code, this line MyUser.fromData(userData.data()); is a constructor in
MyUser class as follows:
class MyUser {
static String uid;
static String name;
static String username;
static String email;
static String userAvatarUrl;
static String location;
static String phoneNumber;
MyUser.fromData(Map<String, dynamic> data) {
uid = data['id'];
name = data['name'];
username = data['username'];
email = data['email'];
userAvatarUrl = data['userAvatarUrl'];
location = data['location'];
phoneNumber = data['phoneNumber'];
}
}
and to make use of all of the following, in each page that i need to load the current user data in, i use for example:
var userId = MyUser.uid
or to show the current user name i use Text('${MyUser.name}');
when i close the app completely and relaunch it again, it should check for authenticity, and complete executing the rest of the code in main() function.
so my questions are:
1) does this have any performance issues when we release the app?
2) does this will really will prevent unnecessary reads that i can consume in every page i need the data in ?
3) is there any better approach to prevent unnecessary reads from firebase, for example to save the current user data as strings and a profile image locally?
pardon me for prolonging the question, but i wanted to share the code itself.
any help would be much appreciated.
As a short answer,
You can make a class of SharedPreferences to store data as strings in key: value manner.
So anywhere you want you can get an instance of that class and reach it from anywhere in the app.
If you also declare some functions which will decode string to json you will get a ready user class instance in return of your function which will make it easier.
So when you want to save user info to Local Storage(SharedPreferences) you may use a function which will encode your User object to string and save it to SharedPreferences as below..
user.dart' as theUser; for conflict issues
class SharedPrefs {
static SharedPreferences _sharedPrefs;
init() async {
if (_sharedPrefs == null) {
_sharedPrefs = await SharedPreferences.getInstance();
}
}
dynamic get user=> _sharedPrefs.getString('user')!=null?theUser.User.fromString(_sharedPrefs.getString('user')):null;
set user(theUser.User user)=> _sharedPrefs.setString('user', jsonEncode(user));
String get accessToken=> _sharedPrefs.getString('access_token');
set accessToken(String accessToken)=> _sharedPrefs.setString('access_token', accessToken);
void removeString(String entry){
_sharedPrefs.remove(entry);
}
}
final sharedPrefs = SharedPrefs();
And in the app anywhere you can use it directly by typing sharedPrefs.user

Can you parse an int from a sqlite database that was originally a bool, back into a bool after querying the database?

I am currently getting a User from a sqlite database I created where I am going to use the data in a FutueBuilder. Now when I store the User data there is a Bool that gets stored in the sqlite database, since sqlite doesn't support boolean types, this gets turned into an int. When I query the user data table, and then run the data through a function that uses the User object to turn the queried data into a user object, it errors out, since the function expects a Boolean, and not an int. What can I do to get around this?
This is where I query the user data table, then send the result to the function to get added to my user list
Future<dynamic> getUser() async {
List _user =[];
final db = await database;
var res = await db.query("user");
if (res.length == 0) {
return null;
}
else {
var resMap = res[0];
return _user.add(User.fromJson(resMap));
}
}
This is the user model and the function that will convert the data into a User object for me. This is where it has an issue due to the model expecting a boolean, but the database now passes it an int since it converted the original boolean to an int.
User userFromJson(String str) => User.fromJson(json.decode(str));
class User {
bool success;
String userID;
String firstName;
String lastName;
String email;
User({this.success, this.userID, this.firstName, this.lastName, this.email});
factory User.fromJson(Map<String, dynamic> json) {
return User(
success: json['success'],
userID: json['UserID'],
firstName: json['FirstName'],
lastName: json['LastName'],
email: json['Email'],
);
}
You can put a ternary operator on your User.fromJson function. Take a look:
factory User.fromJson(Map<String, dynamic> json) {
return User(
success = json['success'] == 1 ? true : false,
userID = json['UserID'],
firstName = json['FirstName'],
lastName = json['LastName'],
email = json['Email'],
);
}
This way if the value is 1 it will set the value to true and if is 0 (or any other value) will set the value to false.

Xamarin.Forms save user in Shared Functions

I saved a token in the mobile with SharedFunctions interface i created
In IOS:
public void SaveAccessToken(string token)
{
NSUserDefaults.StandardUserDefaults.SetString(token, "AccessToken");
}
In Android:
public void SaveAccessToken(string token)
{
var mSharedPrefs = PreferenceManager.GetDefaultSharedPreferences(Android.App.Application.Context);
var mPrefsEditor = mSharedPrefs.Edit();
mPrefsEditor.PutString("AccessToken", token);
mPrefsEditor.Commit();
mPrefsEditor.Dispose();
mSharedPrefs.Dispose();
}
I also want to save a object instead of a string.
Having a look at the documentation of NSUserDefaults, it seems as if writing an object is somewhat restricted, hence I'd suggest you to go another way: Serialize the object using Newtonsoft.JSON (or another JSON library) and write the serialized object.
For iOS:
public void SaveAccessToken<T>(string key, T value)
{
var serializedObject = JsonConvert.SerializeObject(value);
NSUserDefaults.StandardUserDefaults.SetString(serializedObject, key);
}
and similarly for Android
public void SaveAccessToken<T>(string key, T value)
{
var serializedObject = JsonConvert.SerializeObject(value);
var mSharedPrefs = PreferenceManager.GetDefaultSharedPreferences(Android.App.Application.Context);
var mPrefsEditor = mSharedPrefs.Edit();
mPrefsEditor.PutString(serializedObject, key);
mPrefsEditor.Commit();
mPrefsEditor.Dispose();
mSharedPrefs.Dispose();
}

How to read from encrypted CDC in Cassandra

We have implemented TDE for all our tables in Cassandra DSE. We generated a system key using AES/ECB/PKCS5Padding / 128 as cipher algorithm.
We have also enabled cdc for few tables that require cdc capture. Since TDE is enabled for the tables, cdc logs are also encrypted.
We need to push the cdc captures to kafka topics. We tried to decrypt the file using the system_key auto generated in the system_key file.
AES/ECB/PKCS5Padding:128:(key)
But we are getting java.security.InvalidKeyException: Illegal key size or default parameters
Can please advise if this is key can be used for decrypting the cdc logs or suggest any solution.
Below is the snippet we used for decrypting.
public class EncryptDecrypt {
public static String encrypt(String input, String key) {
byte[] crypted = null;
try {
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skey);
crypted = cipher.doFinal(input.getBytes());
} catch (Exception e) {
System.out.println(e.toString());
}
java.util.Base64.Encoder encoder = java.util.Base64.getEncoder();
return new String(encoder.encodeToString(crypted));
}
public static String decrypt(String input, String key) {
byte[] output = null;
try {
java.util.Base64.Decoder decoder = java.util.Base64.getDecoder();
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skey);
output = cipher.doFinal(decoder.decode(input));
} catch (Exception e) {
System.out.println(e.toString());
}
return new String(output);
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String key = "qhk9gDtvTUlLW9dnh/UMaw==";
String data = "ABC";
System.out.println(EncryptDecrypt.encrypt(data, key));
System.out.println(EncryptDecrypt.decrypt(EncryptDecrypt.encrypt(data, key), key));
}
}
The system_key file isn't used for direct encryption of the data, but for encryption of the actual encryption key that is stored in the dse_system.encrypted_keys. These keys are generated for every combination of algorithm/strength. See documentation for more details.

How can the Identity.GetUserId() be made to return a Guid instead of a string?

I am using ASP.Net Identity 2 but soon hope to change to Identity 3 when it becomes more stable (anyone know when that might be?). Here's a sample of my code:
content.ModifiedBy = User.Identity.GetUserId();
The Content table stores ModifedBy as a UNIQUEIDENTIFIER and the Content object assigns a datatype of Guid to ModifiedBy
When I look at the signature for GetUserId() it returns a string.
So how can I take the users UserId and put it into the ModifiedBy which is a Guid?
A guid can take a string as a constructor
content.ModifiedBy = new Guid( User.Identity.GetUserId());
You can use Guid.Parse() or Guid.TryParse()
content.ModifiedBy = Guid.Parse(User.Identity.GetUserId());
https://msdn.microsoft.com/en-us/library/system.guid.parse%28v=vs.110%29.aspx
As I was using same method over and over I added the following extension:
public static class ExtensionMethods
{
public static Guid ToGuid(this string value)
{
Guid result= Guid.Empty;
Guid.TryParse(value, out result);
return result;
}
}
and then I used this:
User.Identity.GetUserId().ToGuid()

Resources