Update readme
This commit is contained in:
parent
f402e8bdf9
commit
aa3e364d3f
304
README.md
304
README.md
@ -1,155 +1,149 @@
|
||||
# NativeCrypto
|
||||
|
||||

|
||||
|
||||
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
|
||||
|
||||
[](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.
|
||||
|
||||

|
||||
|
||||
> 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
|
||||
|
BIN
assets/benchmark_pointycastle.png
Normal file
BIN
assets/benchmark_pointycastle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 120 KiB |
1
example/ios/Flutter/.last_build_id
Normal file
1
example/ios/Flutter/.last_build_id
Normal file
@ -0,0 +1 @@
|
||||
2f8ea5763cdbee83dd665ad298f0e380
|
@ -19,4 +19,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: 1b66dae606f75376c5f2135a8290850eeb09ae83
|
||||
|
||||
COCOAPODS: 1.9.1
|
||||
COCOAPODS: 1.9.3
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user