cryptography 1.2.1 cryptography: ^1.2.1 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. 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 #
Used by #
- 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, and BLAKE2S.
- 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.
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 works only in browsers (Web Cryptography API)
- RSA
- RsaPss (RSA-PSS)
- RsaSsaPkcs1v15 (RSASSA-PKCS1v15)
- Currently works only in browsers (Web Cryptography API)
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.
Key derivation algorithms #
Message authentication codes #
The following MacAlgorithm implementations are available:
Cryptographic hash functions #
The following HashAlgorithm implementations are available:
- blake2s (BLAKE2S)
- sha1 (SHA1)
- sha224 (SHA2-224)
- sha256 (SHA2-256)
- sha384 (SHA2-384)
- sha512 (SHA2-512)
Adding dependency #
In pubspec.yaml:
dependencies:
cryptography: ^1.1.1
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');
}