diff --git a/README.md b/README.md index e7423e8..e9b0b7c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,109 @@ -# NativeCrypto +

+ +

Fast and powerful cryptographic functions for Flutter.
+

-Fast and powerful cryptographic functions thanks to **javax.crypto** , **CommonCrypto** and **CryptoKit**. \ No newline at end of file +

+ +Style: Wyatt Analysis + + + +Maintained with Melos + +

+ +--- + +[[Changelog]](./CHANGELOG.md) | [[License]](./LICENSE) + +--- + +## About + +The goal of this plugin is to provide a fast and powerful cryptographic functions by calling native libraries. On Android, it uses [javax.cypto](https://developer.android.com/reference/javax/crypto/package-summary), and on iOS, it uses [CommonCrypto](https://opensource.apple.com/source/CommonCrypto/) and [CryptoKit](https://developer.apple.com/documentation/cryptokit/) + +I started this projet because I wanted to add cryptographic functions on a Flutter app. But I faced a problem with the well-known [Pointy Castle](https://pub.dev/packages/pointycastle) library: the performance was very poor. Here some benchmarks and comparison: + +![](resources/benchmarks.png) + +For comparison, on a *iPhone 13*, you can encrypt/decrypt a message of **2MiB** in **~5.6s** with PointyCastle and in **~40ms** with NativeCrypto. And on an *OnePlus 5*, you can encrypt/decrypt a message of **50MiB** in **~6min30** with PointyCastle and in less than **~1s** with NativeCrypto. + +In short, NativeCrypto is incomparable with PointyCastle. + +## Usage + +First, check compatibility with your targets. + +| iOS | Android | MacOS | Linux | Windows | Web | +| --- | ------- | ----- | ----- | ------- | --- | +| ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | + +#### Hash + +To digest a message, you can use the following function: + +```dart +Uint8List hash = await HashAlgorithm.sha256.digest(message); +``` + +Note that you can find a `toBytes()` method in the example app, to convert a `String` to a `Uint8List`. + +> In NativeCrypto, you can use the following hash functions: SHA-256, SHA-384, SHA-512 + +#### Keys + +You can build a `SecretKey` from a utf8, base64, base16 (hex) strings or raw bytes. You can also generate a SecretKey from secure random. + +```dart +SecretKey secretKey = SecretKey(Uint8List.fromList([0x73, 0x65, 0x63, 0x72, 0x65, 0x74])); +SecretKey secretKey = SecretKey.fromUtf8('secret'); +SecretKey secretKey = SecretKey.fromBase64('c2VjcmV0'); +SecretKey secretKey = SecretKey.fromBase16('63657274'); +SecretKey secretKey = await SecretKey.fromSecureRandom(256); +``` + +#### Key derivation + +You can derive a `SecretKey` using **PBKDF2**. + +First, you need to initialize a `Pbkdf2` object. + +```dart +Pbkdf2 pbkdf2 = Pbkdf2(32, 1000, algorithm: HashAlgorithm.sha512); +``` + +Then, you can derive a `SecretKey` from a password and salt. + +```dart +SecretKey secretKey = await pbkdf2.derive(password: password, salt: 'salt'); +``` + +> In NativeCrypto, you can use the following key derivation function: PBKDF2 + +#### Cipher + +And now, you can use the `SecretKey` to encrypt/decrypt a message. + +First, you need to initialize a `Cipher` object. + +```dart +AES cipher = AES(secretKey, AESMode.gcm); +``` + +Then, you can encrypt/decrypt your message. + +```dart +CipherText encrypted = await cipher.encrypt(message); +Uint8List decrypted = await cipher.decrypt(encrypted); +``` + +After an encryption, you can use the `CipherText` object to access underlying data. + +```dart +Uint8List iv = encrypted.iv; +Uint8List data = encrypted.data; +Uint8List tag = encrypted.tag; +``` + +Note that data and tag are costly to access, so you should only use them if you need to ! \ No newline at end of file diff --git a/resources/bench_nc_android_oneplus_A5010.csv b/resources/bench_nc_android_oneplus_A5010.csv new file mode 100644 index 0000000..5789c98 --- /dev/null +++ b/resources/bench_nc_android_oneplus_A5010.csv @@ -0,0 +1,14 @@ +Run;Size (B);Encryption Time (ms);Decryption Time (ms) +1;2097152;48;64 +2;6291456;52;52 +3;10485760;105;83 +4;14680064;96;198 +5;18874368;116;143 +6;23068672;253;257 +7;27262976;164;213 +8;31457280;271;270 +9;35651584;339;356 +10;39845888;316;320 +11;44040192;370;412 +12;48234496;425;368 +13;52428800;430;402 \ No newline at end of file diff --git a/resources/bench_nc_ios_iphone13.csv b/resources/bench_nc_ios_iphone13.csv new file mode 100644 index 0000000..47ef2ec --- /dev/null +++ b/resources/bench_nc_ios_iphone13.csv @@ -0,0 +1,14 @@ +Run;Size (B);Encryption Time (ms);Decryption Time (ms) +1;2097152;20;16 +2;6291456;13;13 +3;10485760;16;22 +4;14680064;23;37 +5;18874368;21;48 +6;23068672;34;45 +7;27262976;38;72 +8;31457280;59;72 +9;35651584;70;74 +10;39845888;61;85 +11;44040192;80;92 +12;48234496;90;113 +13;52428800;79;111 \ No newline at end of file diff --git a/resources/bench_pc_android_oneplus_A5010.csv b/resources/bench_pc_android_oneplus_A5010.csv new file mode 100644 index 0000000..48346c9 --- /dev/null +++ b/resources/bench_pc_android_oneplus_A5010.csv @@ -0,0 +1,9 @@ +size;encryption time;encode time;decryption time;crypto time +2000000;7764;7302;0 +4000000;14720;14580;0 +8000000;29421;29037;0 +16000000;58874;58304;0 +32000000;117964;116570;0 +64000000;235122;232923;0 +128000000;469697;466278;0 +256000000;0;0;0 \ No newline at end of file diff --git a/resources/bench_pc_ios_iphone13.csv b/resources/bench_pc_ios_iphone13.csv new file mode 100644 index 0000000..3f01464 --- /dev/null +++ b/resources/bench_pc_ios_iphone13.csv @@ -0,0 +1,14 @@ +Run;Size (B);Encryption Time (ms);Decryption Time (ms) +1;2097152;2420;2289 +2;6291456;7118;7369 +3;10485760;12766;13051 +4;14680064;18594;19029 +5;18874368;27449;27927 +6;23068672;34093;33863 +7;27262976;39855;39981 +8;31457280;46359;46089 +9;35651584;52596;52375 +10;39845888;59151;58881 +11;44040192;65914;65590 +12;48234496;71908;72099 +13;52428800;79202;78571 \ No newline at end of file diff --git a/resources/benchmark_pointycastle.png b/resources/benchmark_pointycastle.png deleted file mode 100644 index 0f35735..0000000 Binary files a/resources/benchmark_pointycastle.png and /dev/null differ diff --git a/resources/benchmarks.png b/resources/benchmarks.png new file mode 100644 index 0000000..62dac68 Binary files /dev/null and b/resources/benchmarks.png differ