Pub Package Github Actions CI

Overview

Popular cryptographic algorithms for Dart / Flutter developers.

Maintained by Gohilla Ltd. Licensed under the Apache License 2.0.

This package is:

  • Easy to use. The API is easy to understand and encourages good defaults.
  • Multi-platform. It's easy to customize implementation of X in platform Y.
  • Fast. By default, we use platform APIs when available. For example, SHA-512 is over 100 times faster than package:crypto in browsers.

Any feedback, issue reports, or pull requests are appreciated!

Some packages that depend on this

Key concepts

Key classes

The usual arguments to algorithms are:

Algorithms by type

Ciphers

The following Cipher implementations are available:

Digital signature algorithms

The following SignatureAlgorithm implementations are available:

  • Ed25519 (curve25519 EdDSA)
    • Performance of the pure Dart implementation is around 200 (signatures or verifications) per second in VM and about 50 in browsers.
  • Elliptic curves approved by NIST
    • Ecdsa.p256 (ECDSA P256 / secp256r1 / prime256v1 + SHA256)
    • Ecdsa.p384 (ECDSA P384 / secp384r1 / prime384v1 + SHA384)
    • Ecdsa.p521 (ECDSA P521 / secp521r1 / prime521v1 + SHA256)
    • We don't have implementations of these in pure Dart.
  • RSA
    • RsaPss (RSA-PSS)
    • RsaSsaPkcs1v15 (RSASSA-PKCS1v15)
    • We don't have implementations of these in pure Dart.

Key exchange algorithms

The following KeyExchangeAlgorithm implementations are available:

  • Elliptic curves approved by NIST
    • Ecdh.p256 (ECDH P256 / secp256r1 / prime256v1)
    • Ecdh.p384 (ECDH P384 / secp384r1 / prime384v1)
    • Ecdh.p521 (ECDH P521 / secp521r1 / prime521v1)
    • We don't have implementations of these in pure Dart.
  • X25519 (curve25519 Diffie-Hellman)
    • Throughput of the pure Dart implementation is around 1000 key agreements per second (in VM).

Key derivation algorithms

The following implementations are available:

Message authentication codes

The following MacAlgorithm implementations are available:

Cryptographic hash functions

The following HashAlgorithm implementations are available:

Available implementations

The abstract class Cryptography has factory methods that return implementations of cryptographic algorithms. The default implementation is BrowserCryptography (which works in all platforms, not just browser). You can write your own Cryptography subclass if you need to.

We wrote the following three implementations of Cryptography:

  • DartCryptography
    • Gives you implementations written in pure Dart implementations. They work in all platforms.
    • SHA1 / SHA2 uses implementation in package:crypto, which is maintained by Google. The rest of the algorithms in DartCryptography are written and tested by us.
    • DartCryptography gives:
      • AesCbc
      • AesCtr
      • AesGcm
      • Blake2b
      • Blake2s
      • Chacha20
      • Chacha20.poly1305Aead
      • Ed25519
      • Hkdf
      • Hmac
      • Pbkdf2
      • Poly1305
      • Sha1
      • Sha224
      • Sha256
      • Sha384
      • Sha512
      • X25519
      • Xchacha20
      • Xchacha20.poly1305Aead
  • BrowserCryptography
    • Extends DartCryptography.
    • Uses Web Cryptography API (crypto.subtle).the
    • In browsers, BrowserCryptography gives:
      • AesCbc
      • AesCtr
      • AesGcm
      • Ecdh.p256
      • Ecdh.p384
      • Ecdh.p512
      • Ecdsa.p256
      • Ecdsa.p384
      • Ecdsa.p512
      • Hkdf
      • Hmac
      • Pbkdf2
      • RsaPss
      • RsaSsaPkcs1v15
      • Sha1
      • Sha256
      • Sha384
      • Sha512
  • FlutterCryptography
    • A Flutter plugin available in cryptography_flutter.
    • Extends BrowserCryptography.
    • Enabled with FlutterCryptography.enable().
    • In Android, FlutterCryptography gives:
      • AesCbc
      • AesCtr
      • AesGcm
      • Chacha20
      • Chacha20.poly1305Aead
    • In iOS, FlutterCryptography gives:
      • AesGcm
      • Chacha20
      • Chacha20.poly1305Aead

Getting started

In pubspec.yaml:

dependencies:
  cryptography: ^2.0.5

If you use Flutter, we recommend that you also add cryptography_flutter:

dependencies:
  cryptography: ^2.0.5
  cryptography_flutter: ^2.0.2

Examples

Digital signature

In this example, we use Ed25519.

import 'package:better_cryptography/better_cryptography.dart';

Future<void> main() async {
  // The message that we will sign
  final message = <int>[1,2,3];

  // Generate a keypair.
  final algorithm = Ed25519();
  final keyPair = await algorithm.newKeyPair();

  // Sign
  final signature = await algorithm.sign(
    message,
    keyPair: keyPair,
  );
  print('Signature: ${signature.bytes}');
  print('Public key: ${signature.publicKey.bytes}');

  // Verify signature
  final isSignatureCorrect = await algorithm.verify(
    message,
    signature: signature,
  );
  print('Correct signature: $isSignatureCorrect');
}

Key agreement

In this example, we use X25519.

import 'package:better_cryptography/better_cryptography.dart';

Future<void> main() async {
  final algorithm = X25519();

  // Alice chooses her key pair
  final aliceKeyPair = await algorithm.newKeyPair();

  // Alice knows Bob's public key
  final bobKeyPair = await algorithm.newKeyPair();
  final bobPublicKey = await bobKeyPair.extractPublicKey();

  // Alice calculates the shared secret.
  final sharedSecret = await algorithm.sharedSecretKey(
    keyPair: aliceKeyPair,
    remotePublicKey: bobPublicKey,
  );
  final sharedSecretBytes = await aliceKeyPair.extractBytes();
  print('Shared secret: $sharedSecretBytes');
}

Authenticated encryption

In this example, we encrypt a message with AesCtr and append a Hmac message authentication code.

import 'dart:convert';
import 'package:better_cryptography/better_cryptography.dart';

Future<void> main() async {
  // Message we want to encrypt
  final message = utf8.encode('Hello encryption!');

  // Choose the cipher
  final algorithm = AesCtr(macAlgorithm: Hmac.sha256()));

  // Generate a random secret key.
  final secretKey = algorithm.newSecretKey();
  final secretKeyBytes = await secretKey.extractBytes();
  print('Secret key: ${secretKeyBytes}');

  // Encrypt
  final secretBox = await algorithm.encrypt(
    message,
    secretKey: secretKey,
  );
  print('Nonce: ${secretBox.nonce}');
  print('Ciphertext: ${secretBox.cipherText}');
  print('MAC: ${secretBox.mac.bytes}');

  // Decrypt
  final clearText = await algorithm.decrypt(
    secretBox,
    secretKey: secretKey,
  );
  print('Cleartext: ${utf8.decode(clearText)}');
}

Hashing

In this example, we use Sha512.

import 'package:better_cryptography/better_cryptography.dart';

Future<void> main() async {
  final sink = Sha512().newHashSink();

  // Add all parts of the authenticated message
  sink.add([1,2,3]);
  sink.add([4,5]);

  // Calculate hash
  sink.close();
  final hash = await sink.hash();

  print('SHA-512 hash: ${hash.bytes}');
}

Libraries

better_cryptography
Cryptographic algorithms for Dart / Flutter developers.
browser
Cryptographic algorithms implemented with browser APIs (Web Cryptography).
dart
Cryptographic algorithms implemented in pure Dart.
helpers
Various helpers for cryptography.