Finish implementing some encryption in the network protocols with AES
This commit is contained in:
parent
38eb7c6acd
commit
84cef345eb
10 changed files with 263 additions and 391 deletions
|
@ -1,80 +1,55 @@
|
|||
import 'dart:typed_data';
|
||||
import 'dart:math';
|
||||
|
||||
class AES {
|
||||
import 'package:encrypt/encrypt.dart';
|
||||
|
||||
class AESData {
|
||||
final List<int> iv;
|
||||
final List<int> data;
|
||||
|
||||
AESData({required this.iv, required this.data});
|
||||
}
|
||||
|
||||
class AESCipher {
|
||||
final Uint8List _aesKey;
|
||||
|
||||
AES._(this._aesKey);
|
||||
AESCipher._(this._aesKey);
|
||||
|
||||
static Future<AES> generate({int aesKeySize = 256}) async {
|
||||
final random = Random.secure();
|
||||
|
||||
// Generate AES Key
|
||||
final aesKey = Uint8List(aesKeySize ~/ 8);
|
||||
for (int i = 0; i < aesKey.length; i++) {
|
||||
aesKey[i] = random.nextInt(256);
|
||||
}
|
||||
|
||||
return AES._(aesKey);
|
||||
static Future<AESCipher> generate({int aesKeySize = 256}) async {
|
||||
return AESCipher._(Key.fromLength(aesKeySize ~/ 8).bytes);
|
||||
}
|
||||
|
||||
static AES useKey(Uint8List key) {
|
||||
AES aes = AES._(key);
|
||||
|
||||
return aes;
|
||||
static AESCipher useKey(Uint8List key) {
|
||||
return AESCipher._(key);
|
||||
}
|
||||
|
||||
Uint8List getKey() {
|
||||
return Uint8List.fromList(_aesKey);
|
||||
}
|
||||
|
||||
Uint8List encrypt(Uint8List data) {
|
||||
return _aesEncrypt(data, _aesKey);
|
||||
Future<AESData> encrypt(Uint8List data) async {
|
||||
final iv = IV.fromLength(16); // Generate a random 16-byte IV
|
||||
final encryptedData = await _aesEncrypt(data, _aesKey, iv);
|
||||
|
||||
return AESData(iv: iv.bytes.toList(), data: encryptedData.toList());
|
||||
}
|
||||
|
||||
Uint8List decrypt(Uint8List encryptedData) {
|
||||
return _aesDecrypt(encryptedData, _aesKey);
|
||||
Future<Uint8List> decrypt(AESData data) async {
|
||||
final iv = IV(Uint8List.fromList(data.iv));
|
||||
return _aesDecrypt(Uint8List.fromList(data.data), _aesKey, iv);
|
||||
}
|
||||
|
||||
static Uint8List _aesEncrypt(Uint8List data, Uint8List key) {
|
||||
final blockSize = 16;
|
||||
final paddedData = _pad(data, blockSize);
|
||||
final encrypted = Uint8List(paddedData.length);
|
||||
static Future<Uint8List> _aesEncrypt(
|
||||
Uint8List data, Uint8List key, IV iv) async {
|
||||
var aes = Encrypter(AES(Key(key), mode: AESMode.cbc));
|
||||
|
||||
for (int i = 0; i < paddedData.length; i += blockSize) {
|
||||
for (int j = 0; j < blockSize; j++) {
|
||||
encrypted[i + j] = paddedData[i + j] ^ key[j % key.length];
|
||||
}
|
||||
}
|
||||
|
||||
return encrypted;
|
||||
final encrypted = await aes.encryptBytes(data.toList(), iv: iv);
|
||||
return encrypted.bytes;
|
||||
}
|
||||
|
||||
static Uint8List _aesDecrypt(Uint8List data, Uint8List key) {
|
||||
final blockSize = 16;
|
||||
final decrypted = Uint8List(data.length);
|
||||
|
||||
for (int i = 0; i < data.length; i += blockSize) {
|
||||
for (int j = 0; j < blockSize; j++) {
|
||||
decrypted[i + j] = data[i + j] ^ key[j % key.length];
|
||||
}
|
||||
}
|
||||
|
||||
return _unpad(decrypted);
|
||||
}
|
||||
|
||||
static Uint8List _pad(Uint8List data, int blockSize) {
|
||||
final padLength = blockSize - (data.length % blockSize);
|
||||
final paddedData = Uint8List(data.length + padLength);
|
||||
paddedData.setAll(0, data);
|
||||
for (int i = data.length; i < paddedData.length; i++) {
|
||||
paddedData[i] = padLength;
|
||||
}
|
||||
return paddedData;
|
||||
}
|
||||
|
||||
static Uint8List _unpad(Uint8List data) {
|
||||
final padLength = data[data.length - 1];
|
||||
return Uint8List.sublistView(data, 0, data.length - padLength);
|
||||
static Future<Uint8List> _aesDecrypt(
|
||||
Uint8List data, Uint8List key, IV iv) async {
|
||||
final aes = Encrypter(AES(Key(key), mode: AESMode.cbc));
|
||||
final decrypted = await aes.decryptBytes(Encrypted(data), iv: iv);
|
||||
return Uint8List.fromList(decrypted);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue