Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
2.8 kB
1
Indexable
Never
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");
}