aes_cryptor.dart 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // aes_cryptor.dart
  2. import 'dart:convert';
  3. import 'dart:typed_data';
  4. import 'package:pointycastle/export.dart';
  5. import 'package:pointycastle/block/aes_fast.dart';
  6. import 'package:pointycastle/macs/hmac.dart';
  7. import 'package:pointycastle/paddings/pkcs7.dart';
  8. import 'package:pointycastle/stream/ctr.dart';
  9. import 'dart:math';
  10. class AESCryptor {
  11. static final BlockCipher _cipher = AESFastEngine();
  12. static Uint8List _generateIv() {
  13. final secureRandom = Random.secure();
  14. final seedData = Uint8List(32);
  15. for (var i = 0; i < seedData.length; i++) {
  16. seedData[i] = secureRandom.nextInt(256);
  17. }
  18. final random = SecureRandom('Fortuna')..seed(KeyParameter(seedData));
  19. return random.nextBytes(_cipher.blockSize);
  20. }
  21. static Uint8List _pad(Uint8List data) {
  22. final padLength = 16 - (data.length % 16);
  23. final paddedData = Uint8List(data.length + padLength)
  24. ..setRange(0, data.length, data);
  25. for (var i = data.length; i < paddedData.length; i++) {
  26. paddedData[i] = padLength;
  27. }
  28. return paddedData;
  29. }
  30. static Uint8List _unpad(Uint8List data) {
  31. final padLength = data[data.length - 1];
  32. return Uint8List.sublistView(data, 0, data.length - padLength);
  33. }
  34. static Uint8List deriveKey(String password) {
  35. final hmac = HMac(SHA256Digest(), 64)
  36. ..init(KeyParameter(Uint8List.fromList(utf8.encode(password))));
  37. final key = Uint8List(32);
  38. hmac.process(Uint8List.fromList([1])); // Can be any constant value.
  39. hmac.doFinal(key, 0);
  40. return key;
  41. }
  42. Uint8List encrypt(Uint8List data, String password) {
  43. final key = deriveKey(password);
  44. final iv = _generateIv();
  45. final params = ParametersWithIV<KeyParameter>(KeyParameter(key), iv);
  46. final encrypter = CTRStreamCipher(_cipher);
  47. encrypter.init(true, params);
  48. final paddedData = _pad(data);
  49. return Uint8List.fromList(iv + encrypter.process(paddedData));
  50. }
  51. Uint8List decrypt(Uint8List data, String password) {
  52. final key = deriveKey(password);
  53. final iv = Uint8List.sublistView(data, 0, 16);
  54. final params = ParametersWithIV<KeyParameter>(KeyParameter(key), iv);
  55. final decrypter = CTRStreamCipher(_cipher);
  56. decrypter.init(false, params);
  57. final decryptedData = decrypter.process(Uint8List.sublistView(data, 16));
  58. return _unpad(decryptedData);
  59. }
  60. }