Update readme

This commit is contained in:
Hugo Pointcheval 2020-12-19 23:07:49 +01:00
parent f402e8bdf9
commit aa3e364d3f
6 changed files with 153 additions and 173 deletions

304
README.md
View File

@ -1,155 +1,149 @@
# NativeCrypto
![native_crypto](/assets/native_crypto.png)
Fast crypto functions for Flutter.
* Table of content
* [Background](#background)
* [Performances](#performances)
* [Installation](#installation)
* [Usage](#usage)
* [Example](#example)
* [How](#how)
* [Todo](#todo)
## Background
🤔 Why I started this project ?
Because I faced a performance issue when I was using **PointyCastle**.
It's quite simple, judge for yourself, these are times for AES256 encryption on an Android device (**Huawei P30 Pro**).
| Size | PointyCastle |
|------|--------------|
| 100 kB | 190 ms
| 200 kB | 314 ms
| 300 kB | 1138 ms
| 400 kB | 2781 ms
| 500 kB | 4691 ms
| 600 kB | 7225 ms
| 700 kB | 10264 ms
| 800 kB | 13582 ms
| 900 kB | 17607 ms
> We notice that these times, in addition to being far too big, are **not even linear**.
## Performances
⏱ On an **Android 10** device: **Huawei P30 Pro**
| Size | NativeCrypto |
|------|--------------|
| 1 mB | 27 ms
| 2 mB | 43 ms
| 3 mB | 78 ms
| 4 mB | 93 ms
| 5 mB | 100 ms
| 10 mB | 229 ms
| 50 mB | 779 ms
## Installation
🚧 You can easely setup a Flutter project with this plugin.
Just add these lines in your **pubspec.yaml**:
```yaml
native_crypto:
git:
url: https://gogs.pointcheval.fr/hugo/native-crypto-flutter.git
ref: v0.0.x
```
> Replace "x" with the current version!
Then in your code:
```dart
// Symmetric crypto.
import 'package:native_crypto/symmetric_crypto.dart';
// To handle exceptions.
import 'package:native_crypto/exceptions.dart';
```
## Usage
To create an AES instance, and generate a key.
```dart
AES aes = AES();
await aes.init(KeySize.bits256)
```
You can also generate key, then use it in AES.
```dart
Uint8List aeskey = await KeyGenerator().secretKey(keySize: KeySize.bits256);
AES aes = AES(key: aeskey);
```
You can create a key with PBKDF2.
```dart
Uint8List key = await KeyGenerator().pbkdf2(password, salt, keyLength: 32, iteration: 10000, digest: Digest.sha256);
AES aes = AES(key: key);
```
Then you can encrypt/decrypt data with this instance.
```dart
encryptedPayload = await aes.encrypt(data);
decryptedPayload = await aes.decrypt(encryptedPayload);
```
Or you can also use AES on the fly with different keys.
```dart
Uint8List aeskey = await KeyGenerator().secretKey(keySize: KeySize.bits256);
encryptedPayload = await AES().encrypt(data, key: aeskey);
decryptedPayload = await AES().decrypt(encryptedPayload, key: aeskey);
```
Available `enums` are:
```dart
enum KeySize { bits128, bits192, bits256 }
enum Digest { sha1, sha256, sha512 }
```
`KeySizes` defines all available key sizes for generation.
`Digest` defines all available digest for PBKDF2.
## Example
🔍 Look in **example/lib/** for an example app.
## How
🔬 But how it is possible ??
Using the native implementation of crypto libs available on each OS.
For **Android**:
* [javax.crypto](https://docs.oracle.com/javase/7/docs/api/javax/crypto/package-summary.html)
* [java.security](https://docs.oracle.com/javase/7/docs/api/java/security/package-summary.html)
For **iOS**:
* [CommonCrypto](https://developer.apple.com/library/archive/documentation/Security/Conceptual/cryptoservices/Introduction/Introduction.html)
## Todos
🚀 You can contribute to this project.
* [x] Implement working cross platform AES encryption/decryption.
* [x] Different key sizes support.
* [x] Improve performances.
* [x] Add exceptions.
* [x] PBKDF2 support.
* [ ] Add other ciphers.
* [ ] Clean platform specific code.
* [ ] Add asym crypto support...
# NativeCrypto for Flutter
[![NativeCrypto Logo](/assets/native_crypto.png)](https://hugo.pointcheval.fr/)
---
Fast and powerful cryptographic functions thanks to **javax.crypto** and **CommonCrypto**.
## 📝 Table of Contents
- [About](#about)
- [Getting Started](#getting_started)
- [Example](#example)
- [Usage](#usage)
- [Built Using](#built_using)
- [Authors](#authors)
## 🧐 About <a name = "about"></a>
The goal of this plugin is to provide simple access to fast and powerful cryptographic functions by calling native libraries. So on **Android** the plugin uses *javax.crypto* and on **iOS** it uses *CommonCrypto*.
I started this project because using **Pointy Castle** I faced big performance issues on smartphone. It's quite simple, an encryption of 1MB of data in AES256 on an Android device takes **20s** with Pointy Castle against **27ms** using NativeCrypto.
![Pointy Castle Benchmark](/assets/benchmark_pointycastle.png)
> We also notice on this benchmark that the AES encryption time does not even increase linearly with size.
As for NativeCrypto, here is a benchmark realized on an Android device, Huawei P30 Pro.
| Size (kB) | NativeCrypto **encryption** time (ms) |
|-----------|---------------------------------------|
| 1 mB | 27 ms
| 2 mB | 43 ms
| 3 mB | 78 ms
| 4 mB | 93 ms
| 5 mB | 100 ms
| 10 mB | 229 ms
| 50 mB | 779 ms
> Less than 1s for 50 mB.
In short, **NativeCrypto** is incomparable to **Pointy Castle** in terms of performance.
## 🏁 Getting Started <a name = "getting_started"></a>
### Prerequisites
You'll need:
- Flutter
### Installing
Add these lines in your **pubspec.yaml**:
```yaml
native_crypto:
git:
url: https://gogs.pointcheval.fr/hugo/native-crypto-flutter.git
ref: v0.0.x
```
> Replace "x" with the current version!
Then in your code:
```dart
import 'package:native_crypto/native_crypto.dart';
```
## 🔍 Example <a name="example"></a>
Look in **example/lib/** for an example app.
## 🎈 Usage <a name="usage"></a>
To derive a key with **PBKDF2**.
```dart
PBKDF2 _pbkdf2 = PBKDF2(keyLength: 32, iteration: 1000, hash: HashAlgorithm.SHA512);
await _pbkdf2.derive(password: "password123", salt: 'salty');
SecretKey key = _pbkdf2.key;
```
To generate a key, and create an **AES Cipher** instance.
```dart
AESCipher aes = await AESCipher.generate(
AESKeySize.bits256,
CipherParameters(
BlockCipherMode.CBC,
PlainTextPadding.PKCS5,
),
);
```
You can also generate key, then create **AES Cipher**.
```dart
SecretKey _key = await SecretKey.generate(256, CipherAlgorithm.AES);
AESCipher aes = AESCipher(
_key,
CipherParameters(
BlockCipherMode.CBC,
PlainTextPadding.PKCS5,
),
);
```
Then you can encrypt/decrypt data with this cipher.
```dart
CipherText cipherText = await aes.encrypt(data);
Uint8List plainText = await aes.decrypt(cipherText);
```
You can easely get encrypted bytes and IV from a CipherText
```dart
Uint8List bytes = cipherText.bytes;
Uint8List iv = cipherText.iv;
```
To create a cipher text with custom data.
```dart
CipherText cipherText = AESCipherText(bytes, iv);
```
To create a hashed message
```dart
MessageDigest md = MessageDigest.getInstance("sha256");
Uint8List hash = md.digest(message);
```
## ⛏️ Built Using <a name = "built_using"></a>
- [Dart](https://dart.dev)
- [Flutter](https://flutter.dev) - Framework
- [Kotlin](https://kotlinlang.org) - Android Specific code
- [Swift](https://www.apple.com/fr/swift/) - iOS Specific code
## ✍️ Authors <a name = "authors"></a>
- [Hugo Pointcheval](https://github.com/hugo-pcl) - Idea & Initial work

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

View File

@ -0,0 +1 @@
2f8ea5763cdbee83dd665ad298f0e380

View File

@ -19,4 +19,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 1b66dae606f75376c5f2135a8290850eeb09ae83
COCOAPODS: 1.9.1
COCOAPODS: 1.9.3

View File

@ -9,11 +9,7 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@ -27,8 +23,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@ -40,13 +34,11 @@
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2DBF05A146610778D425B9D9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@ -62,8 +54,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
D294241BEFD2D3EF500C0577 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -82,9 +72,7 @@
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
@ -230,7 +218,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
@ -319,7 +307,6 @@
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -396,7 +383,6 @@
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -452,7 +438,6 @@
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;

View File

@ -1,6 +1,6 @@
name: native_crypto
description: Fast crypto functions for Flutter.
version: 0.0.4+1
version: 0.0.5+1
author: Hugo Pointcheval
homepage: https://hugo.pointcheval.fr