cryptography 1.0.1 cryptography: ^1.0.1 copied to clipboard
Cryptographic algorithms for digital signature, key agreement, encryption, message authentication, and hashing. X25519, ED25519, AES, Chacha20, and many more.
Overview #
Popular cryptographic algorithms for Dart / Flutter developers. Licensed under the Apache License 2.0.
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 package:crypto, which is maintained by Google and limited to hash functions.
- We wrote pure Dart implementations for X25519, ChaCha20 family, AES-CBC, AES-CTR, HKDF, HMAC, Poly1305, and BLAKE2S. We also added support for use of Web Cryptography API (NIST elliptic curves, AES) in browsers.
- The APIs generally include both asynchronous and synchronous methods.for instance,
sharedSecret(...)
andsharedSecretSync(...)
). - 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 #
- NIST elliptic curves (read about the algorithm)
- x25519 (read about the algorithm)
- X25519 (curve25519 Diffie-Hellman) is our recommendation for new applications. It's used in technologies such as SSH, TLS, Signal, WhatsApp, and Wireguard. Performance of our Dart implementation is about 1k exchanges per second on a Macbook Pro.
For more more documentation, see KeyExchangeAlgorithm.
Digital signature algorithms #
- NIST elliptic curves (read about the algorithm)
- ecdsaP256Sha256 (ECDSA P256 / secp256r1 / prime256v1)
- ecdsaP384Sha256 (ECDSA P384 / secp384r1 / prime384v1)
- ecdsaP521Sha256 (ECDSA P521 / secp521r1 / prime521v1)
- Currently NIST elliptic curves are only supported in browsers (Web Cryptography API).
- ed25519 (read about the algorithm)
- ED25519 (curve25519 EdDSA) is our recommendation for new applications. Performance of our Dart implementation is about 200 signatures or verifications per second.
For more more documentation, see SignatureAlgorithm.
Symmetric encryption #
- NIST AES (read about the algorithm)
- Chacha20 family (read about the algorithm)
- chacha20
- chacha20Poly1305Aead (AEAD_CHACHA20_POLY1305)
- xchacha20
- xchacha20Poly1305Aead (AEAD_XCHACHA20_POLY1305)
- Chacha20 (AEAD) is our recommendation for new applications. It's used in technologies such as TLS, SSH, Signal, and Wireguard. Performance of our Dart implementation is about 50-100MB/s on a Macbook Pro.
For more more documentation, see Cipher.
Key derivation algorithms #
Message authentication codes #
For more more documentation, see MacAlgorithm.
Cryptographic hash functions #
- blake2s (BLAKE2S)
- sha1 (SHA1)
- sha224 (SHA2-224)
- sha256 (SHA2-256)
- sha384 (SHA2-384)
- sha512 (SHA2-512)
For more more documentation, see HashAlgorithm.
Adding dependency #
In pubspec.yaml:
dependencies:
cryptography: ^1.0.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');
}