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 = '';
setState(() { if (megabytes != null) {
output = await _benchmark(megabytes);
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,63 +125,87 @@ class _MyAppState extends State<MyApp> {
centerTitle: true, centerTitle: true,
title: const Text('Native Crypto'), title: const Text('Native Crypto'),
), ),
body: Padding( body: SingleChildScrollView(
padding: const EdgeInsets.fromLTRB(20, 10, 10, 20), child: Padding(
child: Center( padding: const EdgeInsets.fromLTRB(20, 10, 10, 20),
child: Column( child: Center(
children: <Widget>[ child: Column(
TextField( children: <Widget>[
controller: textController, TextField(
decoration: InputDecoration( controller: textController,
hintText: 'Text to encrypt.', decoration: InputDecoration(
hintText: 'Text to encrypt.',
),
), ),
), 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), )),
)), (encrypted.cipherText != null && encrypted.cipherText.isNotEmpty)
(encryptedPayload != null && encryptedPayload.isNotEmpty) ? Text(encrypted.cipherText.toString())
? Text(encryptedPayload.first.toList().toString()) : Container(),
: Container(), FlatButton(
FlatButton( onPressed: _decrypt,
onPressed: decrypt, color: Colors.blue,
color: Colors.blue, child: Text(
child: Text( 'Decrypt String',
'Decrypt String', style: TextStyle(color: Colors.white),
style: TextStyle(color: Colors.white), )),
)), SizedBox(height: 20),
SizedBox(height: 20), // Output
// Output Text(
Text(_output, _output,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),), style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
SizedBox(height: 20), ),
FlatButton( SizedBox(height: 20),
onPressed: () {benchmark(1);}, FlatButton(
color: Colors.blue, onPressed: () {
child: Text( _testPerf(megabytes: 1);
'Benchmark 1 MB', },
style: TextStyle(color: Colors.white), color: Colors.blue,
)), child: Text(
FlatButton( 'Benchmark 1 MB',
onPressed: () {benchmark(10);}, style: TextStyle(color: Colors.white),
color: Colors.blue, )),
child: Text( FlatButton(
'Benchmark 10 MB', onPressed: () {
style: TextStyle(color: Colors.white), _testPerf(megabytes: 10);
)), },
FlatButton( color: Colors.blue,
onPressed: () {benchmark(50);}, child: Text(
color: Colors.blue, 'Benchmark 10 MB',
child: Text( style: TextStyle(color: Colors.white),
'Benchmark 50 MB', )),
style: TextStyle(color: Colors.white), FlatButton(
)), onPressed: () {
], _testPerf(megabytes: 50);
},
color: Colors.blue,
child: Text(
'Benchmark 50 MB',
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(),
],
),
), ),
), ),
), ),
@ -177,3 +213,19 @@ class _MyAppState extends State<MyApp> {
); );
} }
} }
/// 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;
}
}