native_crypto 0.8.1
native_crypto: ^0.8.1 copied to clipboard
Fast AES, MD5, SHA and HMAC cryptographic functions, using built-in system API, with hardware-acceleration (if supported).
native_crypto #
Fast AES, MD5, SHA and HMAC cryptographic functions, using built-in system API.
Hardware-acceleration enabled. (if Platform API and device support)
Disclaimer #
This package is provided "as-is" without any warranties. The author is not liable for any damages or losses resulting from the use of this software. Use it at your own risk.
Platform Support #
Windows | Android | Linux | iOS | macOS | web |
---|---|---|---|---|---|
✅ | ✅ | ✅ | ❌ Help Wanted |
❌ Help Wanted |
❌ Never support |
Platform API & Harware acceleration #
No 3rd party library inside.
All cryptographic functions provided in this package directly call the system APIs, so some of these functions may benefit from hardware acceleration (if supported by the system).
Platform | Link mode | System built-in API |
---|---|---|
Android | jni | javax.crypto.Cipher |
Windows | ffi | CNG BCrypt |
Linux | ffi | OpenSSL EVP |
iOS MacOS |
ffi | CommonCryptor AES & MD5 & SHA |
For iOS & macOS platform ( Help Wanted ) #
In theory, this package should be able to run on both iOS and macOS. Since I have no iOS or macOS devices, I would appreciate it if someone could help modify the relevant files such as the *.podspec.
Features #
- AES
- AES-CBC
- AES-ECB
- AES-CFB
- AES-CTR (Windows not support)
- MD5
- SHA
- SHA-1
- SHA-224 (Windows not support)
- SHA-256
- SHA-384
- SHA-512
- HMAC
- HMAC-MD5
- HMAC-SHA1
- HMAC-SHA224 (Windows not support)
- HMAC-SHA256
- HMAC-SHA384
- HMAC-SHA512
Installation #
Add this to your package's pubspec.yaml
file:
dependencies:
native_crypto:
dependency_overrides: ## IMPORTANT !!!
jni:
git:
url: https://github.com/jakky1/native.git
ref: only_jni
Please make sure to include the dependency_overrides
section; otherwise, you will encounter build errors when compiling the app for Windows or Linux.
The original jni package will try to link to JVM in Windows / Linux.
For Linux platform #
In Ubuntu Linux (for example), the following packages need to be installed during development:
sudo apt install libssl-dev
Functions #
MD5 algorithm #
For example, get MD5 of a file:
var hash = NCrypto.md5(); // use MD5 algorithm
await File(filePath).openRead().pipe(hash);
log("hashing result: $hash"); // file MD5 hex string
Uint8List? bytes = hash.bytes; // file MD5 result (byte array)
// `hash.bytes` will be `null` if stream not closed
In the above code, NCrypto.md5()
object is passed into pipe()
.
You can put NCrypto.md5()
into transform()
instead. For example, download a file and calculate the MD5 value of the file at the same time:
String url = "https://...";
var httpClient = HttpClient();
var request = await httpClient.getUrl(Uri.parse(url));
var response = await request.close();
var hash = NCrypto.md5(); // use MD5 algorithm
var fileSink = File(savePath).openWrite();
await response.transform(hash).pipe(fileSink); // pass into transform()
fileSink.close();
log("file downloaded. MD5: $hash"); // file MD5 hex string
You can also get the MD5 of a List<int>:
log("md5 of string => ${NCrypto.md5().convert(utf8.encode("test"))}");
SHA algorithm #
Just replace NCrypto.md5()
to the following code:
NCrypto.md5()
NCrypto.sha1()
NCrypto.sha224() // Windows not support
NCrypto.sha256()
NCrypto.sha384()
NCrypto.sha512()
HMAC algorithm #
For example, calculate HMAC-SHA512 of a file:
var key = NCrypto.newHMacKey(); // create new secure random key for HMAC
var hmac = NCrypto.hmacSha512(key);
await File(filePath).openRead().pipe(hmac);
log("HMac result: $hmac"); // file HMAC-SHA512 hex string
Uint8List? bytes = hmac.bytes; // file HMAC-SHA512 result (byte array)
You can also pass NCrypto.hmacSha512(key)
into .transform()
:
var hmac = NCrypto.hmacSha512(key);
await response.transform(hmac).pipe(fileSink); // pass into transform()
To use another algorithm in HMAC, just replace NCrypto.hmacSha512(key)
with the following code:
NCrypto.hmacMd5(key) // HMAC-MD5
NCrypto.hmacSha1(key) // HMAC-SHA1
NCrypto.hmacSha224(key) // HMAC-SHA224
NCrypto.hmacSha256(key) // HMAC-SHA256
NCrypto.hmacSha384(key) // HMAC-SHA384
NCrypto.hmacSha512(key) // HMAC-SHA512
AES algorithm #
For example, encrypt a file with AES-CBC algorithm:
// select AES-CBC algorithm
var cipher = NCrypto.aesCbc;
// secure randomly generate 32-bytes secret key for AES-256
var key = cipher.newKey256();
// secure randomly generate 16-bytes IV (nonce)
var iv = cipher.newIV();
await File(srcFile)
.openRead()
.transform(cipher.encrypt(key, iv)) // encrypt data
.pipe(fileSink);
To decrypt a file:
await File(srcFile)
.openRead()
.transform(cipher.decrypt(key, iv)) // decrypt data
.pipe(fileSink);
There are 3 ways to generate secret key:
var key = cipher.newKey128(); // secure randomly generate 16-bytes secret key for AES-128
var key = cipher.newKey192(); // secure randomly generate 24-bytes secret key for AES-192
var key = cipher.newKey256(); // secure randomly generate 32-bytes secret key for AES-256
Use the following code to select different AES algorithm:
var cipher = NCrypto.aesCbc; // AES-CBC, safe, suggested
var cipher = NCrypto.aesEcb; // AES-ECB, not safe
var cipher = NCrypto.aesCfb; // AES-CFB, safe
var cipher = NCrypto.aesCtr; // AES-CTR, safe & fast (Windows not support)
Just encode / decode bytes:
List<int> data = <int>[...];
List<int> encryptedBytes = NCrypto.aesCbc.encrypt(key, iv).convert(data);
List<int> decryptedBytes = NCrypto.aesCbc.decrypt(key, iv).convert(encryptedBytes);
// `data` should equal to `decryptedBytes`
AES-ECB #
When using NCrypto.aesEcb
, don't provide IV, or exception occurs:
var cipher = NCrypto.aesEcb;
var key = cipher.newKey256();
//var iv = cipher.newIV(); // don't use IV in AES-ECB
await File(srcFile)
.openRead()
.transform(cipher.encrypt(key)) // don't pass `IV` in AES-ECB
.pipe(fileSink);
Known limitation #
- Windows not support the following algorithms:
- AES-CTR
- SHA-224
- HMAC-SHA224
- in iOS & macOS, CommonCrypto framework don't support AES-GCM
- CryptoKit is another built-in framework on iOS and macOS, supporting additional functions such as AES-GCM, SHA-512/224, SHA-512/256, ChaCha20, Ed25519, EDCH, and more. However, CryptoKit does not support the C language and can only be called using Swift, which makes it unusable for developers like me who do not have a macOS device. I look forward to someone developing related functionality in the future.
My other packages #
- native_zip : A Flutter FFI plugin for fast, easy-to-use, multi-threaded ZIP file operations. Implemented in native C code.