cryptography 1.4.0 cryptography: ^1.4.0 copied to clipboard
Cryptographic algorithms for encryption, digital signatures, key agreement, authentication, and hashing. AES, Chacha20, ED25519, X25519, and more. Web Crypto support.
Overview #
Popular cryptographic algorithms for Dart / Flutter developers. Copyright 2019-2020 Gohilla Ltd. Licensed under the Apache License 2.0.
This package is:
- Safe. Plenty of tests. No license risks. Used in commercial products.
- Fast. For example, SHA-512 in browsers can be 100 times faster than package:crypto.
Any feedback, issue reports, or pull requests are appreciated!
Links #
Related packages #
- kms
- A Dart package for hardware-based or cloud-based key management solutions.
- kms_flutter
- Uses native APIs for storing cryptographic keys in Android and iOS.
- noise_protocol
- An implementation of Noise handshake protocol.
- Add your project here?
Some things to know #
- SHA1 and SHA2 implementations use the package crypto, which is maintained by Google and contains only hash functions and HMAC.
- We wrote pure Dart implementations for X25519, ED25519, RSA-PSS, ChaCha20 / XChacha20, AES-CBC, AES-CTR, AES-GCM, HKDF, HMAC, Poly1305, BLAKE2S, and BLAKE2B.
- We implemented automatic use of Web Cryptography API (crypto.subtle) when you use SHA1, SHA2, AES, ECDH, ECDSA, or RSA in browsers.
- The APIs generally include both asynchronous and synchronous methods. Only the
asynchronous methods are able to use Web Crypto APIs. For instance, you can calculate a SHA-512
hash with
sha512.hash(bytes)
orsha512.hashSync(bytes)
. In browsers, asynchronous version can be as much as 100 times faster. In other platforms the synchronous version is slightly faster. We recommend that developers use asynchronous methods. - If Dart SDK decides to expose BoringSSL functions (SDK issue), we will use them as much as possible.
Using operating system APIs of Android, iOS, and Mac OS X #
The package cryptography_flutter optimizes performance of some cryptographic algorithms by using native APIs of Android, iOS, and Mac OS X. You must use asynchronous methods to get the performance boost.
Cryptographic material classes #
- SecretKey is used by symmetric cryptography.
- KeyPair
(PrivateKey
and PublicKey)
is used by asymmetric cryptography.
- Many data formats exist for storing RSA and elliptic curve keys. This package contains JSON Web Key (JWK) implementations JwkPrivateKey and JwkPublicKey.
- Nonce ("initialization vector", "IV", or "salt") is some non-secret, unique value required by many functions.
Available algorithms #
Key exchange algorithms #
The following KeyExchangeAlgorithm implementations are available:
- Elliptic curves approved by NIST (read about the algorithm)
- x25519 (curve25519 Diffie-Hellman)
- In our benchmarks, the performance is around 1k operations per second in VM.
For more more documentation, see KeyExchangeAlgorithm.
Digital signature algorithms #
The following SignatureAlgorithm implementations are available:
- ed25519 (curve25519 EdDSA)
- In our benchmarks, the performance is around 200 signatures or verifications per second in VM (about 50 in browsers).
- Elliptic curves approved by NIST (read about the algorithm)
- ecdsaP256Sha256 (ECDSA P256 / secp256r1 / prime256v1 + SHA256)
- ecdsaP384Sha256 (ECDSA P384 / secp384r1 / prime384v1 + SHA256)
- ecdsaP384Sha384 (ECDSA P384 / secp384r1 / prime384v1 + SHA384)
- ecdsaP521Sha256 (ECDSA P521 / secp521r1 / prime521v1 + SHA256)
- ecdsaP521Sha512 (ECDSA P521 / secp521r1 / prime521v1 + SHA512)
- Currently implemented only in browsers.
- RSA
- RsaPss (RSA-PSS)
- RsaSsaPkcs1v15 (RSASSA-PKCS1v15)
- Currently implemented only in browsers.
Symmetric encryption #
The following Cipher implementations are available:
- CipherWithAppendedMac adds authentication (such as HMAC-SHA256) to ciphers without built-in authentication.
- AES (read about the algorithm)
- Chacha20 family (read about the algorithm)
- chacha20
- chacha20Poly1305Aead (AEAD_CHACHA20_POLY1305)
- xchacha20
- xchacha20Poly1305Aead (AEAD_XCHACHA20_POLY1305)
- In our benchmarks, the performance is around 40-140MB/s in VM.
Password hashing algorithms #
- Pbkdf2 (PBKDF2)
Key derivation algorithms #
Message authentication codes #
The following MacAlgorithm implementations are available:
Cryptographic hash functions #
The following HashAlgorithm implementations are available:
- blake2b (BLAKE2B)
- blake2s (BLAKE2S)
- sha1 (SHA1)
- sha224 (SHA2-224)
- sha256 (SHA2-256)
- sha384 (SHA2-384)
- sha512 (SHA2-512)
Getting started #
In pubspec.yaml:
dependencies:
cryptography: ^1.4.0
Examples #
Key agreement with X25519 #
In this example, we use x25519.
import 'package:cryptography/cryptography.dart';
Future<void> main() async {
// Let's generate two X25519 keypairs.
final localKeyPair = await x25519.newKeyPair();
final remoteKeyPair = await x25519.newKeyPair();
// We can now calculate a shared 256-bit secret
final secretKey = await x25519.sharedSecret(
localPrivateKey: localKeyPair.privateKey,
remotePublicKey: remoteKeyPair.publicKey,
);
final secretBytes = await secretKey.extract();
print('Shared secret: $secretBytes');
}
Digital signature with ED25519 #
In this example, we use ed25519.
import 'package:cryptography/cryptography.dart';
Future<void> main() async {
// The message that we will sign
final message = <int>[1,2,3];
// Generate a random ED25519 keypair
final keyPair = await ed25519.newKeyPair();
// Sign
final signature = await ed25519.sign(
message,
keyPair,
);
print('Signature: ${signature.bytes}');
print('Public key: ${signature.publicKey.bytes}');
// Verify signature
final isSignatureCorrect = await ed25519.verify(
message,
signature,
);
print('Is the signature correct: $isSignatureCorrect');
}
Authenticated encryption with Chacha20 + Poly1305 #
In this example, we use chacha20Poly1305Aead, a standard that uses ChaCha20 and Poly1305.
import 'package:cryptography/cryptography.dart';
Future<void> main() async {
// Choose the cipher
final cipher = chacha20Poly1305Aead;
// Choose some 256-bit secret key
final secretKey = SecretKey.randomBytes(32);
// Choose some unique (non-secret) 96-bit nonce.
// The same (secretKey, nonce) combination should not be used twice!
final nonce = Nonce.randomBytes(12);
// Our message
final message = utf8.encode('encrypted message');
// Encrypt
final encrypted = await cipher.encrypt(
message,
secretKey: secretKey,
nonce: nonce,
);
print('Encrypted: $encrypted');
// Decrypt
final decrypted = await cipher.decrypt(
encrypted,
secretKey: secretKey,
nonce: nonce,
);
print('Decrypted: $decrypted');
}
Authenticated encryption with AES-CTR + HMAC-SHA256 #
In this example, we encrypt a message with aesCtr and append a Hmac message authentication code.
import 'package:cryptography/cryptography.dart';
Future<void> main() async {
// Choose the cipher
final cipher = CipherWithAppendedMac(aesCtr, Hmac(sha256));
// Choose some 256-bit secret key
final secretKey = SecretKey.randomBytes(16);
// Choose some unique (non-secret) nonce (max 16 bytes).
// The same (secretKey, nonce) combination should not be used twice!
final nonce = Nonce.randomBytes(12);
// Our message
final message = utf8.encode('encrypted message');
// Encrypt
final encrypted = await cipher.encrypt(
message,
secretKey: secretKey,
nonce: nonce,
);
print('Encrypted: $encrypted');
// Decrypt
final decrypted = await cipher.decrypt(
encrypted,
secretKey: secretKey,
nonce: nonce,
);
print('Decrypted: $decrypted');
}
Message authentication with HMAC-BLAKE2S #
In this example, we use Hmac and blake2s.
import 'package:cryptography/cryptography.dart';
import 'dart:convert';
Future<void> main() {
// Choose a secret key
final secretKey = SecretKey(utf8.encode('authentication secret'));
// Create a HMAC-BLAKE2S sink
final macAlgorithm = const Hmac(blake2s);
final sink = macAlgorithm.newSink(secretKey: secretKey);
// Add all parts of the authenticated message
sink.add([1,2,3]);
sink.add([4,5]);
// Calculate MAC
sink.close();
final macBytes = sink.mac.bytes;
print('Message authentication code: $macBytes');
}