cryptography 1.0.4 cryptography: ^1.0.4 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:
- Commercially used. Unlike some other open-source packages, this package doesn't have license issues. Correctness and audit-friendliness critical to us.
- Fast. For example, our benchmarks show that SHA-512 performance in browsers can be over 100 times faster than package:crypto by Google (thanks to use of platform APIs).
- Easy. This is probably the easiest-to-use cryptographic package written in Dart.
Any feedback, issue reports, or pull requests are appreciated! See our Github project.
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 protocol, which can be used for secure communications.
- 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, ChaCha20 family, AES-CBC, AES-CTR, HKDF, HMAC, Poly1305, and BLAKE2S.
- We implemented automatic use of Web Cryptography API (SHA1, SHA2, AES, NIST elliptic curves) in browsers.
- The APIs generally include both asynchronous and synchronous methods. For instance, you can
calculate a SHA-256 hash with
sha256.hash(bytes)
orsha256.hashSync(bytes)
. We recommend that you use asynchronous methods because they are able to take advantage of asynchronous platform APIs such as Web Cryptography API.
Available algorithms #
Key exchange algorithms #
Key exchange algorithms are subclasses of KeyExchangeAlgorithm. The following implementations are available:
- Elliptic curves approved by NIST (read about the algorithm)
- x25519 (read about the algorithm)
- X25519 (curve25519 Diffie-Hellman) is a popular, often-recommended key agreement algorithm. In our benchmarks, we observe performance of around 1k operations per second in VM.
For more more documentation, see KeyExchangeAlgorithm.
Digital signature algorithms #
Signature algorithms are subclasses of SignatureAlgorithm. The following implementations are available:
- ed25519 (read about the algorithm)
- ED25519 (curve25519 EdDSA) is a popular, often-recommended signature algorithm. In our benchmarks, we observe performance of 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 these elliptic curves are only supported in browsers (Web Cryptography API).
Symmetric encryption #
Ciphers are subclasses of Cipher. The following implementations are available:
- AES (read about the algorithm)
- Chacha20 family (read about the algorithm)
- chacha20
- chacha20Poly1305Aead (AEAD_CHACHA20_POLY1305)
- xchacha20
- xchacha20Poly1305Aead (AEAD_XCHACHA20_POLY1305)
- Chacha20 is a popular cipher and it's our recommendation if you can choose an algorithm. In our benchmarks, we observe performance of around 20-100MB/s in VM.
Key derivation algorithms #
Message authentication codes #
Message authentication algorithms are subclasses of MacAlgorithm. The following implementations are available:
Cryptographic hash functions #
Hash functions are subclasses of HashAlgorithm. The following 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.0.2
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');
}