Created
March 12, 2023 17:42
-
-
Save ologunB/f37afe92a78c6193981fd225f1d35120 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:convert'; | |
import 'dart:io'; | |
import 'package:flutter/foundation.dart'; | |
import 'package:mms_app/core/storage/local_storage.dart'; | |
import 'package:path_provider/path_provider.dart'; | |
import 'package:sodium_libs/sodium_libs_sumo.dart'; | |
class EncryptionTool { | |
static late Sodium sodium; | |
static Future<void> init() async { | |
sodium = await SodiumSumoInit.init(); | |
} | |
static KeyPair generatePair() { | |
KeyPair keyPair = sodium.crypto.box.keyPair(); | |
return keyPair; | |
} | |
static bool shitTestKeyPair(String pubKey, String secretKey) { | |
try { | |
Uint8List data = base64Decode('data'); | |
Uint8List pub = base64Decode(pubKey); | |
Uint8List secret = base64Decode(secretKey); | |
/// seal the [data] with public key | |
final encrypted = sodium.crypto.box.seal(message: data, publicKey: pub); | |
/// unseal the [data] with given public and private keys | |
final decryptedKeys = sodium.crypto.box.sealOpen( | |
cipherText: encrypted, | |
publicKey: pub, | |
secretKey: SecureKey.fromList(sodium, secret), | |
); | |
return listEquals(decryptedKeys, data); | |
} catch (e) { | |
print(e); | |
return false; | |
} | |
} | |
static Future<EncryptedFile> encryptData(File file) async { | |
final Uint8List messageBytes = await file.readAsBytes(); | |
print('normal data in mb: ${0.000001 * messageBytes.length}'); | |
final nonce = sodium.randombytes.buf(sodium.crypto.secretBox.nonceBytes); | |
final SecureKey key = sodium.crypto.secretBox.keygen(); | |
// encrypt data here | |
final encryptedData = sodium.crypto.secretBox.easy( | |
message: messageBytes, | |
nonce: nonce, | |
key: key, | |
); | |
Map<String, List> keys = { | |
'nonce': nonce, | |
'key': key.extractBytes(), | |
}; | |
// seal the key with public key | |
final encryptedKeys = sodium.crypto.box.seal( | |
message: Uint8List.fromList(jsonEncode(keys).codeUnits), | |
publicKey: AppCache.getUser()!.getPubKey(), | |
); | |
print('encrypted data in mb: ${0.000001 * encryptedData.length}'); | |
return EncryptedFile(encryptedData, base64Encode(encryptedKeys)); | |
} | |
static Future<Uint8List> decryptData( | |
Uint8List cipherText, String encryptedKey) async { | |
print('decrypted data in mb: ${0.000001 * cipherText.length}'); | |
// get private key | |
Uint8List? key = await readPrivateKey(); | |
// unseal the key with public and private keys | |
final decryptedKeys = sodium.crypto.box.sealOpen( | |
cipherText: base64Decode(encryptedKey), | |
publicKey: AppCache.getUser()!.getPubKey(), | |
secretKey: SecureKey.fromList(sodium, key!), | |
); | |
Map<String, dynamic> keys = jsonDecode(String.fromCharCodes(decryptedKeys)); | |
// decrypt data here | |
final decryptedData = sodium.crypto.secretBox.openEasy( | |
cipherText: cipherText, | |
nonce: Uint8List.fromList(keys['nonce']!.cast<int>()), | |
key: SecureKey.fromList( | |
sodium, Uint8List.fromList(keys['key']!.cast<int>())), | |
); | |
return decryptedData; | |
} | |
static Future<String> shareData(String key, String receiverPubKey) async { | |
// get private key | |
Uint8List? secretKey = await readPrivateKey(); | |
// unseal the [key] with public and private keys | |
final decryptedKeys = sodium.crypto.box.sealOpen( | |
cipherText: base64Decode(key), | |
publicKey: AppCache.getUser()!.getPubKey(), | |
secretKey: SecureKey.fromList(sodium, secretKey!), | |
); | |
// seal the receiver public key | |
final encryptedKeys = sodium.crypto.box.seal( | |
message: decryptedKeys, | |
publicKey: base64Decode(receiverPubKey), | |
); | |
return base64Encode(encryptedKeys); | |
} | |
static savePrivateKey(String key) async { | |
Directory dir = await getApplicationDocumentsDirectory(); | |
String filesPath = dir.path; | |
String? name = AppCache.getUser()?.id; | |
final file = File('$filesPath/$name.secret'); | |
if (!file.existsSync()) file.createSync(); | |
IOSink s = file.openWrite(mode: FileMode.write); | |
s.write(key); | |
await s.close(); | |
} | |
static Future<String?> readKey() async { | |
Directory dir = await getApplicationDocumentsDirectory(); | |
String filesPath = dir.path; | |
String? name = AppCache.getUser()?.id; | |
if (name == null) return null; | |
final file = File('$filesPath/$name.secret'); | |
if (!file.existsSync()) return null; | |
return file.readAsStringSync(); | |
} | |
static Future<Uint8List?> readPrivateKey() async { | |
String? val = await readKey(); | |
if (val == null) return null; | |
return base64Decode(val); | |
} | |
} | |
class EncryptedFile { | |
String key; | |
Uint8List file; | |
EncryptedFile(this.file, this.key); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment