Skip to content

Commit aa878f5

Browse files
committed
Improves support for operating system APIs in cryptography_flutter.
In "package:cryptography" 2.5.0: * Adds enough DER encoding/decoding support for us to use Apple's CryptoKit ECDH/ECDSA functions. * Improves BrowserHmac/etc. parameter checks. * Improves documentation. In "package:cryptography_flutter" 2.3.0: * Adds support for algorithms. In this version, the following operating system API adapters pass tests: * Android: * FlutterAesGcm * FlutterChacha20.poly1305Aead() * FlutterHmac.sha1() * FlutterHmac.sha224() * FlutterHmac.sha256() * FlutterHmac.sha384() * FlutterHmac.sha512() * FlutterPbkdf2() * Apple operating systems: * FlutterAesGcm * FlutterChacha20.poly1305Aead() * FlutterEd25519() * FlutterEcdh.p256() * FlutterEcdh.p384() * FlutterEcdh.p521() * FlutterEcdsa.p256() * FlutterEcdsa.p384() * FlutterEcdsa.p521() * FlutterHmac.sha256() * FlutterHmac.sha512() * FlutterX25519() * Requires "package:cryptography" 2.5.0, which has enough DER encoding/decoding support for us to use Apple's CryptoKit ECDH/ECDSA functions. * Adds support for reading names of crypto providers in Android. * Adds more tests.
1 parent 5968b35 commit aa878f5

File tree

81 files changed

+4096
-1470
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+4096
-1470
lines changed

.github/FUNDING.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github: [terrier989]
2+
open_collective: [cryptography]

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,16 @@ Maintained by [gohilla.com](https://gohilla.com). Licensed under the [Apache Lic
1111
## Packages
1212
* [cryptography](cryptography)
1313
* Cryptography API for Dart / Flutter.
14-
* Contains cryptography implementations written in pure Dart.
15-
* Contains cryptography implementations that use Web Cryptography API in browsers.
14+
* Contains cryptographic algorithm implementations written in pure Dart.
15+
* Contains cryptographic algorithm implementations that use Web Cryptography API in browsers.
1616
* [cryptography_flutter](cryptography_flutter)
17-
* Contains cryptography implementations that use Android / iOS APIs.
17+
* Contains cryptographic algorithm implementations that use operating system APIs in Android
18+
and Apple operating systems (iOS, Mac OS X, etc.).
19+
* [cryptography_flutter_integration_test](cryptography_flutter_integration_test)
20+
* Integration test project for "cryptography_flutter".
21+
* [cryptography_test](cryptography_flutter)
22+
* Cross-platform tests. Note that "cryptography" and "cryptography_flutter_integration_test"
23+
contain more tests than just these.
1824
* [jwk](jwk)
1925
* JWK (JSON Web Key) encoding / decoding.
2026

cryptography/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.5.0
2+
* Adds enough DER encoding/decoding support for us to use Apple's CryptoKit ECDH/ECDSA functions.
3+
* Improves BrowserHmac/etc. parameter checks.
4+
* Improves documentation.
5+
16
## 2.4.0
27
* Fixes many issues found by adding more tests. Also improves documentation.
38
* Improves performance of SHA256, HMAC, and PBKDF2 by cutting unnecessary state allocations and

cryptography/README.md

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
Popular cryptographic algorithms for [Dart](https://dart.dev) / [Flutter](https://flutter.dev)
77
developers.
88

9-
Maintained by Gohilla. Licensed under the [Apache License 2.0](LICENSE).
9+
Maintained by [gohilla.com](https://gohilla.com). Licensed under the [Apache License 2.0](LICENSE).
1010

11-
This package is:
11+
This package is designed to be:
1212

1313
* __Easy to use__. The API is easy to understand and encourages good defaults.
1414
* __Multi-platform__. It's easy to customize implementation of X in platform Y.
@@ -26,11 +26,15 @@ Any feedback, issue reports, or pull requests are appreciated!
2626

2727
# Getting started
2828

29+
If you use Flutter, it's recommended (but not necessarily) that you also import our sibling package
30+
[cryptography_flutter](https://pub.dev/packages/cryptography_flutter), which improves performance
31+
by using operating system APIs.
32+
2933
In _pubspec.yaml_:
3034
```yaml
3135
dependencies:
32-
cryptography: ^2.4.0
33-
cryptography_flutter: ^2.2.0 # Remove this if you are writing a pure Dart package without Flutter
36+
cryptography: ^2.5.0
37+
cryptography_flutter: ^2.3.0 # Remove if you don't use Flutter
3438
```
3539
3640
You are ready to go!
@@ -39,14 +43,16 @@ You are ready to go!
3943
4044
Please report bugs at [github.com/dint-dev/cryptography/issues](https://github.com/dint-dev/cryptography/issues).
4145
42-
If you want discuss cryptography in Flutter/Dart projects with other developers, feel free to join
43-
our community discussion at [github.com/dint-dev/cryptography/discussions](https://github.com/dint-dev/cryptography/discussions):
44-
* Your experiences with the documentation and API design?
45-
* What is the best way to achieve X?
46-
* Etc.
46+
Having questions? Feel free to use our Github Discussions at
47+
[github.com/dint-dev/cryptography/discussions](https://github.com/dint-dev/cryptography/discussions).
48+
49+
50+
# Some things to know
51+
## General guidance on cryptography
52+
Please read [information about Mobile App Cryptography](https://mas.owasp.org/MASTG/General/0x04g-Testing-Cryptography/)
53+
by OWASP. It contains a lot of useful information that helps you build more secure software.
4754
48-
# Concepts
49-
## Cryptographic keys
55+
## Common parameters
5056
* [SecretKey](https://pub.dev/documentation/cryptography/latest/cryptography/SecretKey-class.html)
5157
* Used by ciphers, message authentication codes, and key derivation functions.
5258
* [KeyPair](https://pub.dev/documentation/cryptography/latest/cryptography/KeyPair-class.html)
@@ -63,9 +69,6 @@ our community discussion at [github.com/dint-dev/cryptography/discussions](https
6369
(P-256 / P-384 / P-512 public keys)
6470
* [RsaPublicKey](https://pub.dev/documentation/cryptography/latest/cryptography/RsaPublicKey-class.html)
6571
(RSA public keys)
66-
* Nonces (also known as "IV", "Initialization Vector", "salt") are non-secret byte sequences.
67-
* AAD (Additional Authenticated Data) is some additional byte sequence that you want a cipher to
68-
authenticate when you encrypt/decrypt.
6972
7073
Note that SecretKey and KeyPair instances are opaque and asynchronous by default. They may not be in
7174
the memory and may not be readable at all. If a SecretKey or KeyPair instance is in memory, it's an
@@ -92,7 +95,7 @@ three types of wands:
9295
9396
In the future version 3.x, we plan to transition to wands as the default API for doing operations.
9497
95-
### Ciphers
98+
## Ciphers
9699
97100
The following [Cipher](https://pub.dev/documentation/cryptography/latest/cryptography/Cipher-class.html)
98101
implementations are available:
@@ -118,7 +121,7 @@ implementations are available:
118121
* [Xchacha20.poly1305Aead](https://pub.dev/documentation/cryptography/latest/cryptography/Xchacha20/Xchacha20.poly1305Aead.html) (
119122
AEAD_XCHACHA20_POLY1305)
120123
121-
### Digital signature algorithms
124+
## Digital signature algorithms
122125
123126
The
124127
following [SignatureAlgorithm](https://pub.dev/documentation/cryptography/latest/cryptography/SignatureAlgorithm-class.html)
@@ -143,7 +146,7 @@ implementations are available:
143146
RSASSA-PKCS1v15)
144147
* We don't have implementations of these in pure Dart.
145148
146-
### Key exchange algorithms
149+
## Key exchange algorithms
147150
148151
The following [KeyExchangeAlgorithm](https://pub.dev/documentation/cryptography/latest/cryptography/KeyExchangeAlgorithm-class.html)
149152
implementations are available:
@@ -169,15 +172,15 @@ The following implementations are available:
169172
* [Pbkdf2](https://pub.dev/documentation/cryptography/latest/cryptography/Pbkdf2-class.html) (
170173
PBKDF2)
171174
172-
### Message authentication codes
175+
## Message authentication codes
173176
174177
The following [MacAlgorithm](https://pub.dev/documentation/cryptography/latest/cryptography/MacAlgorithm-class.html)
175178
implementations are available:
176179
177180
* [Hmac](https://pub.dev/documentation/cryptography/latest/cryptography/Hmac-class.html)
178181
* [Poly1305](https://pub.dev/documentation/cryptography/latest/cryptography/Poly1305-class.html)
179182
180-
### Cryptographic hash functions
183+
## Cryptographic hash functions
181184
182185
The following [HashAlgorithm](https://pub.dev/documentation/cryptography/latest/cryptography/HashAlgorithm-class.html)
183186
implementations are available:
@@ -202,7 +205,7 @@ lots of small hashes, the advantage is even bigger because this package allows y
202205
state. Therefore our HMAC-SHA256 is much faster too. In browsers, hashes can be over 100 times
203206
faster because this package automatically uses Web Crypto API.
204207
205-
### Random number generators
208+
## Random number generators
206209
207210
We continue to use the old good `Random.secure()` as the default random number in all APIs.
208211

cryptography/lib/src/browser/browser_cryptography.dart

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class BrowserCryptography extends DartCryptography {
150150

151151
@override
152152
Ecdsa ecdsaP256(HashAlgorithm hashAlgorithm) {
153-
if (isSupported && hashAlgorithm is BrowserHashAlgorithmMixin) {
153+
if (isSupported && hashAlgorithm is Sha256) {
154154
return BrowserEcdsa.p256(
155155
hashAlgorithm,
156156
random: _random,
@@ -161,7 +161,7 @@ class BrowserCryptography extends DartCryptography {
161161

162162
@override
163163
Ecdsa ecdsaP384(HashAlgorithm hashAlgorithm) {
164-
if (isSupported && hashAlgorithm is BrowserHashAlgorithmMixin) {
164+
if (isSupported && hashAlgorithm is Sha384) {
165165
return BrowserEcdsa.p384(
166166
hashAlgorithm,
167167
random: _random,
@@ -172,7 +172,7 @@ class BrowserCryptography extends DartCryptography {
172172

173173
@override
174174
Ecdsa ecdsaP521(HashAlgorithm hashAlgorithm) {
175-
if (isSupported && hashAlgorithm is BrowserHashAlgorithmMixin) {
175+
if (isSupported && hashAlgorithm is Sha512) {
176176
return BrowserEcdsa.p521(
177177
hashAlgorithm,
178178
random: _random,
@@ -183,11 +183,14 @@ class BrowserCryptography extends DartCryptography {
183183

184184
@override
185185
Hkdf hkdf({required Hmac hmac, required int outputLength}) {
186-
if (isSupported && hmac is BrowserHmac) {
187-
return BrowserHkdf(
188-
hmac: hmac,
189-
outputLength: outputLength,
190-
);
186+
if (isSupported) {
187+
if (BrowserHashAlgorithmMixin.hashAlgorithmNameFor(hmac.hashAlgorithm) !=
188+
null) {
189+
return BrowserHkdf(
190+
hmac: hmac,
191+
outputLength: outputLength,
192+
);
193+
}
191194
}
192195
return super.hkdf(
193196
hmac: hmac,

cryptography/lib/src/browser/ecdsa.dart

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ import 'dart:math';
1616
import 'dart:typed_data';
1717

1818
import 'package:cryptography/cryptography.dart';
19-
import 'package:cryptography/src/browser/hash.dart';
2019

2120
import '_javascript_bindings.dart' as web_crypto;
2221
import 'browser_ec_key_pair.dart';
22+
import 'hash.dart';
2323

2424
class BrowserEcdsa extends Ecdsa {
2525
@override
26-
final BrowserHashAlgorithmMixin hashAlgorithm;
26+
final HashAlgorithm hashAlgorithm;
2727

2828
@override
2929
final KeyPairType keyPairType;
@@ -34,23 +34,23 @@ class BrowserEcdsa extends Ecdsa {
3434
}) : super.constructor();
3535

3636
BrowserEcdsa.p256(
37-
BrowserHashAlgorithmMixin hashAlgorithm, {
37+
HashAlgorithm hashAlgorithm, {
3838
Random? random,
3939
}) : this(
4040
keyPairType: KeyPairType.p256,
4141
hashAlgorithm: hashAlgorithm,
4242
);
4343

4444
BrowserEcdsa.p384(
45-
BrowserHashAlgorithmMixin hashAlgorithm, {
45+
HashAlgorithm hashAlgorithm, {
4646
Random? random,
4747
}) : this(
4848
keyPairType: KeyPairType.p384,
4949
hashAlgorithm: hashAlgorithm,
5050
);
5151

5252
BrowserEcdsa.p521(
53-
BrowserHashAlgorithmMixin hashAlgorithm, {
53+
HashAlgorithm hashAlgorithm, {
5454
Random? random,
5555
}) : this(
5656
keyPairType: KeyPairType.p521,
@@ -96,7 +96,9 @@ class BrowserEcdsa extends Ecdsa {
9696
final byteBuffer = await web_crypto.sign(
9797
web_crypto.EcdsaParams(
9898
name: 'ECDSA',
99-
hash: hashAlgorithm.webCryptoName,
99+
hash: BrowserHashAlgorithmMixin.hashAlgorithmNameFor(
100+
hashAlgorithm,
101+
)!,
100102
),
101103
jsCryptoKey,
102104
web_crypto.jsArrayBufferFrom(message),
@@ -120,15 +122,18 @@ class BrowserEcdsa extends Ecdsa {
120122
'Public key should be an instance of EcPublicKey, not: $publicKey',
121123
);
122124
}
125+
final hashAlgorithmName = BrowserHashAlgorithmMixin.hashAlgorithmNameFor(
126+
hashAlgorithm,
127+
)!;
123128
final jsCryptoKey = await jsPublicKeyFrom(
124129
signature.publicKey,
125130
webCryptoCurve: keyPairType.webCryptoCurve!,
126-
webCryptoHash: hashAlgorithm.webCryptoName,
131+
webCryptoHash: hashAlgorithmName,
127132
);
128133
return await web_crypto.verify(
129134
web_crypto.EcdsaParams(
130135
name: 'ECDSA',
131-
hash: hashAlgorithm.webCryptoName,
136+
hash: hashAlgorithmName,
132137
),
133138
jsCryptoKey,
134139
web_crypto.jsArrayBufferFrom(signature.bytes),

cryptography/lib/src/browser/hash.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@ mixin BrowserHashAlgorithmMixin implements HashAlgorithm {
3232
);
3333
return Hash(Uint8List.view(byteBuffer));
3434
}
35+
36+
static String? hashAlgorithmNameFor(HashAlgorithm hashAlgorithm) {
37+
if (hashAlgorithm is Sha1) {
38+
return 'SHA-1';
39+
}
40+
if (hashAlgorithm is Sha256) {
41+
return 'SHA-256';
42+
}
43+
if (hashAlgorithm is Sha384) {
44+
return 'SHA-384';
45+
}
46+
if (hashAlgorithm is Sha512) {
47+
return 'SHA-512';
48+
}
49+
return null;
50+
}
3551
}
3652

3753
/// [Sha1] implementation that uses _Web Cryptography API_ in browsers.

cryptography/lib/src/browser/hkdf.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@
1515
import 'dart:typed_data';
1616

1717
import 'package:cryptography/cryptography.dart';
18+
import 'package:cryptography/src/browser/hash.dart';
1819

1920
import '_javascript_bindings.dart' show jsArrayBufferFrom;
2021
import '_javascript_bindings.dart' as web_crypto;
21-
import 'hmac.dart';
2222

2323
/// HKDF implementation that uses _Web Cryptography API_ in browsers.
2424
///
2525
/// See [BrowserCryptography].
2626
class BrowserHkdf extends Hkdf {
2727
@override
28-
final BrowserHmac hmac;
28+
final Hmac hmac;
2929

3030
@override
3131
final int outputLength;
@@ -43,7 +43,9 @@ class BrowserHkdf extends Hkdf {
4343
final byteBuffer = await web_crypto.deriveBits(
4444
web_crypto.HkdfParams(
4545
name: 'HKDF',
46-
hash: hmac.hashAlgorithmWebCryptoName,
46+
hash: BrowserHashAlgorithmMixin.hashAlgorithmNameFor(
47+
hmac.hashAlgorithm,
48+
)!,
4749
salt: jsArrayBufferFrom(nonce),
4850
info: jsArrayBufferFrom(info),
4951
),

0 commit comments

Comments
 (0)