Skip to content

Commit

Permalink
feat: decrypt screenshot in isolate
Browse files Browse the repository at this point in the history
  • Loading branch information
diyews committed Nov 22, 2021
1 parent 0e77b14 commit 403eddb
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 10 deletions.
66 changes: 65 additions & 1 deletion lib/cbc_cipher.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:isolate';
import 'dart:typed_data';

import 'package:pointycastle/export.dart' hide State;
Expand All @@ -6,14 +7,29 @@ import 'package:shared_preferences/shared_preferences.dart';
class CBCCipher {
static Uint8List aesKey = Uint8List(0);

static void setAESKey(Uint8List key, [bool isSync = true]) {
aesKey = key;
if (isSync) {
CBCCipherIsolate.syncKey();
}
}

static Future<void> initKey() async {
final prefs = await SharedPreferences.getInstance();
final key = prefs.getString('encrypt_key') ?? '';
if (key.isNotEmpty) {
aesKey = Uint8List.fromList(key.codeUnits);
setAESKey(Uint8List.fromList(key.codeUnits));
}
}

static Future<void> initIsolate() async {
final receivePort = ReceivePort();
await Isolate.spawn(_handler, receivePort.sendPort);
final sendPort = await receivePort.first;
CBCCipherIsolate.initSendPort(sendPort);
await CBCCipherIsolate.syncKey();
}

static Uint8List processBodyBytes(Uint8List bodyBytes) {
final iv = Uint8List.sublistView(bodyBytes, 0, aesKey.length);
final cipherText = Uint8List.sublistView(bodyBytes, aesKey.length);
Expand All @@ -33,3 +49,51 @@ class CBCCipher {
paddedPlainText, 0, paddedPlainText.length - paddedPlainText.last);
}
}

class CBCCipherIsolate {
static SendPort? _sendPort;

static initSendPort(SendPort sendPort) {
_sendPort = sendPort;
}

static Future syncKey() {
return _send(_sendPort!, {'type': 'update_key', 'data': CBCCipher.aesKey});
}

static Future processBodyBytesIsolate(Uint8List bodyBytes) {
return _send(_sendPort!, {'type': 'decrypt', 'data': bodyBytes});
}
}

Future _send(SendPort port, msg) {
final response = ReceivePort();
port.send([msg, response.sendPort]);
return response.first;
}

Future<void> _handler(SendPort sendPort) async {
final port = ReceivePort();
sendPort.send(port.sendPort);

await for (var msg in port) {
final request = msg[0];
SendPort replyTo = msg[1];

switch (request['type']) {
case 'update_key':
CBCCipher.setAESKey(request['data'], false);
replyTo.send('Done');
break;
case 'decrypt':
final decrypted = CBCCipher.processBodyBytes(request['data']);
replyTo.send(decrypted);
break;
case 'test':
replyTo.send('Done');
break;
default:
replyTo.send('Done');
}
}
}
11 changes: 5 additions & 6 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:shared_preferences/shared_preferences.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await CBCCipher.initIsolate();
await CBCCipher.initKey();
runApp(const MyApp());
}
Expand All @@ -34,16 +35,14 @@ class MyApp extends StatelessWidget {
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(),
home: const MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key) {
CBCCipher.initKey();
}
const MyHomePage({Key? key}) : super(key: key);

// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
Expand Down Expand Up @@ -171,8 +170,8 @@ Future<String> _openEditEncryptKeyDialog(BuildContext context) async {
onPressed: () {
final text = _controller.text;
prefs.setString('encrypt_key', text);
CBCCipher.aesKey = Uint8List.fromList(text.codeUnits);
Navigator.of(context).pop(_controller.text);
CBCCipher.setAESKey(Uint8List.fromList(text.codeUnits));
Navigator.of(context).pop(text);
},
child: const Text('OK')),
],
Expand Down
5 changes: 2 additions & 3 deletions lib/scrcpy.dart
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,8 @@ class _ScreenShotState extends State<_ScreenShot> {
running = false;
return;
}
setState(() {
imageBytes = CBCCipher.processBodyBytes(res.bodyBytes);
});
imageBytes = await CBCCipherIsolate.processBodyBytesIsolate(res.bodyBytes);
setState(() {});
running = false;
if (widget.screenShotModel.mode == _ScreenShotMode.one) {
return;
Expand Down

0 comments on commit 403eddb

Please sign in to comment.