Add example of AES api usage

This commit is contained in:
Hugo Pointcheval 2020-04-15 17:43:33 +02:00
parent 77a4055154
commit f5b6bfc717

View File

@ -1,11 +1,11 @@
// Copyright (c) 2020 // Copyright (c) 2020
// Author: Hugo Pointcheval // Author: Hugo Pointcheval
import 'dart:developer';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:native_crypto/native_crypto.dart'; import 'package:native_crypto/symmetrical_crypto.dart';
void main() => runApp(MyApp()); void main() => runApp(MyApp());
@ -17,19 +17,20 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> { class _MyAppState extends State<MyApp> {
final textController = TextEditingController(); final textController = TextEditingController();
String _output = 'none'; String _output = 'none';
String _bench;
Uint8List aeskey; AES aes = AES();
List<Uint8List> encryptedPayload; Encrypted encrypted = Encrypted();
Uint8List decryptedPayload; Uint8List decryptedPayload;
void generateKey() async { void _generateKey() async {
aeskey = await NativeCrypto().symKeygen(); await aes.init(KeySize.bits256);
setState(() { setState(() {
_output = 'Key generated.'; _output = 'Key generated.';
}); });
} }
void encrypt() async { void _encrypt() async {
final plainText = textController.text.trim(); final plainText = textController.text.trim();
var output; var output;
@ -37,7 +38,7 @@ class _MyAppState extends State<MyApp> {
output = 'Entry is empty'; output = 'Entry is empty';
} else { } else {
var stringToBytes = TypeHelper().stringToBytes(plainText); var stringToBytes = TypeHelper().stringToBytes(plainText);
encryptedPayload = await NativeCrypto().symEncrypt(stringToBytes, aeskey); encrypted = await aes.encrypt(stringToBytes);
output = 'String successfully encrypted.'; output = 'String successfully encrypted.';
} }
setState(() { setState(() {
@ -45,56 +46,67 @@ class _MyAppState extends State<MyApp> {
}); });
} }
void decrypt() async { void _decrypt() async {
var output; var output;
if (encryptedPayload == null || encryptedPayload.isEmpty) { if (encrypted.cipherText == null || encrypted.cipherText.isEmpty) {
output = 'Encrypt before decrypting!'; output = 'Encrypt before decrypting!';
} else { } else {
decryptedPayload = await NativeCrypto().symDecrypt(encryptedPayload, aeskey); decryptedPayload = await aes.decrypt(encrypted);
output = 'String successfully decrypted:\n\n${TypeHelper().bytesToString(decryptedPayload)}'; var bytesToString = TypeHelper().bytesToString(decryptedPayload);
output = 'String successfully decrypted:\n\n$bytesToString';
} }
setState(() { setState(() {
_output = output; _output = output;
}); });
} }
void benchmark(int megabytes) async { Future<String> _benchmark(int megabytes) async {
String output;
var output;
var bigFile = Uint8List(megabytes * 1000000); var bigFile = Uint8List(megabytes * 1000000);
var before = DateTime.now(); var before = DateTime.now();
var encryptedBigFile = await NativeCrypto().symEncrypt(bigFile, aeskey); var encryptedBigFile = await aes.encrypt(bigFile);
var after = DateTime.now(); var after = DateTime.now();
var benchmark = after.millisecondsSinceEpoch - before.millisecondsSinceEpoch; var benchmark =
after.millisecondsSinceEpoch - before.millisecondsSinceEpoch;
output = '$megabytes MB\n\nAES Encryption:\n$benchmark ms\n\n'; output = '$megabytes MB\n\nAES Encryption:\n$benchmark ms\n\n';
var beforeDec = DateTime.now(); before = DateTime.now();
var decryptedBigFile = await NativeCrypto().symDecrypt(encryptedBigFile, aeskey); await aes.decrypt(encryptedBigFile);
var afterDec = DateTime.now(); after = DateTime.now();
print(bigFile.length); benchmark = after.millisecondsSinceEpoch - before.millisecondsSinceEpoch;
print(decryptedBigFile.length);
print(listEquals(bigFile, decryptedBigFile)); output += 'AES Decryption:\n$benchmark ms\n\n\n';
var benchmarkDec = afterDec.millisecondsSinceEpoch - beforeDec.millisecondsSinceEpoch; return output;
}
output += 'AES Decryption:\n$benchmarkDec ms';
void _testPerf({int megabytes}) async {
var output = '';
if (megabytes != null) {
output = await _benchmark(megabytes);
setState(() { setState(() {
_output = output; _output = output;
}); });
} else {
setState(() {
_bench = 'Open the logcat!';
});
for (int i=1;i<100;i+=10) {
var benchmark = await _benchmark(i);
log(benchmark);
}
}
} }
@override @override
void initState() { void initState() {
// Generate AES key on init. // Generate AES instance on init.
generateKey(); _generateKey();
super.initState(); super.initState();
} }
@ -113,7 +125,8 @@ class _MyAppState extends State<MyApp> {
centerTitle: true, centerTitle: true,
title: const Text('Native Crypto'), title: const Text('Native Crypto'),
), ),
body: Padding( body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 10, 20), padding: const EdgeInsets.fromLTRB(20, 10, 10, 20),
child: Center( child: Center(
child: Column( child: Column(
@ -126,17 +139,17 @@ class _MyAppState extends State<MyApp> {
), ),
SizedBox(height: 20), SizedBox(height: 20),
FlatButton( FlatButton(
onPressed: encrypt, onPressed: _encrypt,
color: Colors.blue, color: Colors.blue,
child: Text( child: Text(
'Encrypt String', 'Encrypt String',
style: TextStyle(color: Colors.white), style: TextStyle(color: Colors.white),
)), )),
(encryptedPayload != null && encryptedPayload.isNotEmpty) (encrypted.cipherText != null && encrypted.cipherText.isNotEmpty)
? Text(encryptedPayload.first.toList().toString()) ? Text(encrypted.cipherText.toString())
: Container(), : Container(),
FlatButton( FlatButton(
onPressed: decrypt, onPressed: _decrypt,
color: Colors.blue, color: Colors.blue,
child: Text( child: Text(
'Decrypt String', 'Decrypt String',
@ -144,36 +157,75 @@ class _MyAppState extends State<MyApp> {
)), )),
SizedBox(height: 20), SizedBox(height: 20),
// Output // Output
Text(_output, Text(
_output,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),), style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
SizedBox(height: 20), SizedBox(height: 20),
FlatButton( FlatButton(
onPressed: () {benchmark(1);}, onPressed: () {
_testPerf(megabytes: 1);
},
color: Colors.blue, color: Colors.blue,
child: Text( child: Text(
'Benchmark 1 MB', 'Benchmark 1 MB',
style: TextStyle(color: Colors.white), style: TextStyle(color: Colors.white),
)), )),
FlatButton( FlatButton(
onPressed: () {benchmark(10);}, onPressed: () {
_testPerf(megabytes: 10);
},
color: Colors.blue, color: Colors.blue,
child: Text( child: Text(
'Benchmark 10 MB', 'Benchmark 10 MB',
style: TextStyle(color: Colors.white), style: TextStyle(color: Colors.white),
)), )),
FlatButton( FlatButton(
onPressed: () {benchmark(50);}, onPressed: () {
_testPerf(megabytes: 50);
},
color: Colors.blue, color: Colors.blue,
child: Text( child: Text(
'Benchmark 50 MB', 'Benchmark 50 MB',
style: TextStyle(color: Colors.white), style: TextStyle(color: Colors.white),
)), )),
SizedBox(height: 20),
FlatButton(
onPressed: () {
_testPerf();
},
color: Colors.blue,
child: Text(
'Full benchmark',
style: TextStyle(color: Colors.white),
)),
(_bench != null && _bench.isNotEmpty)
? Text(_bench)
: Container(),
], ],
), ),
), ),
), ),
), ),
),
); );
} }
} }
/// Contains some useful functions.
class TypeHelper {
/// Returns bytes `Uint8List` from a `String`.
Uint8List stringToBytes(String source) {
var list = source.codeUnits;
var bytes = Uint8List.fromList(list);
return bytes;
}
/// Returns a `String` from bytes `Uint8List`.
String bytesToString(Uint8List bytes) {
var string = String.fromCharCodes(bytes);
return string;
}
}