import 'dart:convert';
import 'package:hex/hex.dart';
import 'package:cryptography/cryptography.dart';
class Cryptography {
static List<int> getValidPassword(String origPassword, int maxLength) {
var origBytes = utf8.encode(origPassword).toList();
var len = origPassword.length;
if (len < maxLength) {
origBytes.addAll(List<int>.filled(maxLength - len, 0x00));
} else if (len > maxLength) {
origBytes = origBytes.sublist(0, maxLength);
}
return origBytes;
}
static Future<String> encrypt(List<int> data, String password) async {
final pwBytes = getValidPassword(password, 16);
final algorithm = AesGcm.with128bits();
final secretKey = await algorithm.newSecretKeyFromBytes(pwBytes);
final nonce = algorithm.newNonce();
final secretBox = await algorithm.encrypt(
data,
secretKey: secretKey,
nonce: nonce,
);
final hexNonce = HEX.encode(nonce);
final hexCipher = HEX.encode(secretBox.cipherText);
final hexMac = HEX.encode(secretBox.mac.bytes);
return "$hexNonce/$hexCipher/$hexMac";
}
static DecodedData decodeCipherString(String encryptedString) {
final split = encryptedString.split("/");
if (split.length != 3) {
throw Exception("Invalid cipher text size");
}
final hexNonce = split[0];
final hexCipher = split[1];
final hexMac = split[2];
final decoded = DecodedData()
..nonce = HEX.decode(hexNonce)
..cipherText = HEX.decode(hexCipher)
..mac = HEX.decode(hexMac);
return decoded;
}
static Future<List<int>> decrypt(
String encryptedString, String password) async {
final pwBytes = getValidPassword(password, 16);
final algorithm = AesGcm.with128bits();
final decoded = decodeCipherString(encryptedString);
final secretBox = SecretBox(decoded.cipherText,
nonce: decoded.nonce, mac: Mac(decoded.mac));
final secretKey = await algorithm.newSecretKeyFromBytes(pwBytes);
final decrypted = await algorithm.decrypt(secretBox, secretKey: secretKey);
return decrypted;
}
}
class DecodedData {
List<int> nonce = [];
List<int> cipherText = [];
List<int> mac = [];
}
void main(List<String> arguments) async {
final data =
"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks.";
final password = "Bitcoin";
print(
"Original message is: $data. Password for encryption/decryption is: $password");
print("First, let's encrypt");
final encryptedString =
await Cryptography.encrypt(utf8.encode(data), password);
print("Encrypted string is: $encryptedString");
print("Now, let's decrypt");
final decrypted = await Cryptography.decrypt(encryptedString, password);
final decryptedMsg = utf8.decode(decrypted);
print("Decrypted message is: $decryptedMsg");
}