Skip to content

Commit

Permalink
v2.10.0
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasroussel committed Aug 23, 2023
1 parent 1e69c81 commit 3847ffc
Show file tree
Hide file tree
Showing 9 changed files with 314 additions and 36 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 2.10.0

- New ECDSA algorithm (ES256K)
- New RSA algorithm with PSS padding (PS256, PS384, PS512)
- README.md improved
- example/example.dart improved

## 2.9.1

- Adding a new class factory `ECPublicKey.cert`
Expand Down Expand Up @@ -127,7 +134,7 @@

## 1.6.0

- New ECDSA Algorithm (EC256, EC384, EC512)
- New ECDSA Algorithm (ES256, ES384, ES512)
- ECPrivateKey and ECPublicKey, two new keys for ECDSA algorithm
- PrivateKey is renamed in RSAPrivateKey
- PublicKey is renamed in RSAPublicKey
Expand Down
95 changes: 74 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ JSON Web Tokens are an open, industry standard RFC 7519 method for representing

https://jwt.io allows you to decode, verify and generate JWT.

## Examples

Check out the [Example File](https://github.com/jonasroussel/dart_jsonwebtoken/blob/main/example/example.dart) for a full example code of all the differents algorithms.

## Usage

### Import
Expand All @@ -19,27 +23,22 @@ import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
### Creating & signing a JWT

```dart
// Create a json web token
// Pass the payload to be sent in the form of a map
// Generate a JSON Web Token
// You can provide the payload as a key-value map or a string
final jwt = JWT(
// Payload
{
'id': 123,
'server': {
'id': '3e4fc296',
'loc': 'euw-2',
}
},
issuer: 'https://github.com/jonasroussel/dart_jsonwebtoken',
);
// Sign it (default with HS256 algorithm)
token = jwt.sign(SecretKey('secret passphrase'));
final token = jwt.sign(SecretKey('secret passphrase'));
print('Signed token: $token\n');
```
Expand All @@ -48,7 +47,7 @@ print('Signed token: $token\n');

```dart
try {
// Verify a token
// Verify a token (SecretKey for HMAC & PublicKey for all the others)
final jwt = JWT.verify(token, SecretKey('secret passphrase'));
print('Payload: ${jwt.payload}');
Expand All @@ -60,23 +59,77 @@ try {
```

### You can also, decode the token without checking its signature

```dart
final jwt = JWT.decode(token);
print('Payload: ${jwt.payload}');
```

### Keys creation for all the algorithms

The raw PEM content provided here is intended for learning purposes. In a production environment, it's recommended to read the private and public keys from separate files. Then, you can pass the content of these files (as strings) in the parameters

```dart
// H256, H384, H512
final hmacKey = SecretKey('secret passphrase');
// RS256, RS384, RS512, PS256, PS384, PS512
final rsaPrivKey = RSAPrivateKey('''
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAq5QLAv9kYTgelglIhC17KdfUoinkwvQ4F0TZAp7qgmu19dCx
...
-----END RSA PRIVATE KEY-----
''');
// You can also extract the public key from a certificate with RSAPublicKey.cert(...)
final rsaPubKey = RSAPublicKey('''
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq5QLAv9kYTgelglIhC17
...
-----END PUBLIC KEY-----
'''
);
// ES256, ES256K, ES384, ES512
final ecPrivKey = ECPrivateKey('''
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2
...
-----END PRIVATE KEY-----
''');
// You can also extract the public key from a certificate with ECPublicKey.cert(...)
final ecPubKey = ECPublicKEy('''
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEVs/o5+uQbTjL3chynL4wXgUg2R9
...
-----END PUBLIC KEY-----
''');
// EdDSA (PEM parsing is not available for EdDSA keys)
final edPrivKey = EdDSAPrivateKey([1, 42, 12, 84, ...]);
final edPubKey = EdDSAPublicKey([1, 42, 12, 84, ...]);
```

### Supported Algorithms

| JWT Algorithms | Digital Signature or MAC Algorithm |
| -------------- | ---------------------------------------------------- |
| HS256 | HMAC using SHA-256 hash algorithm |
| HS384 | HMAC using SHA-384 hash algorithm |
| HS512 | HMAC using SHA-512 hash algorithm |
| RS256 | RSASSA-PKCS1-v1_5 using SHA-256 hash algorithm |
| RS384 | RSASSA-PKCS1-v1_5 using SHA-384 hash algorithm |
| RS512 | RSASSA-PKCS1-v1_5 using SHA-512 hash algorithm |
| ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm |
| ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm |
| ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm |
| EdDSA | EdDSA using ed25519 curve and SHA-512 hash algorithm |
| JWT Algorithms | Digital Signature or MAC Algorithm |
| -------------- | ----------------------------------------------------- |
| HS256 | HMAC using SHA-256 hash algorithm |
| HS384 | HMAC using SHA-384 hash algorithm |
| HS512 | HMAC using SHA-512 hash algorithm |
| PS256 | RSASSA-PSS using SHA-256 hash algorithm |
| PS384 | RSASSA-PSS using SHA-384 hash algorithm |
| PS512 | RSASSA-PSS using SHA-512 hash algorithm |
| RS256 | RSASSA-PKCS1-v1_5 using SHA-256 hash algorithm |
| RS384 | RSASSA-PKCS1-v1_5 using SHA-384 hash algorithm |
| RS512 | RSASSA-PKCS1-v1_5 using SHA-512 hash algorithm |
| ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm |
| ES256K | ECDSA using secp256k curve and SHA-256 hash algorithm |
| ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm |
| ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm |
| EdDSA | EdDSA using ed25519 curve and SHA-512 hash algorithm |
5 changes: 5 additions & 0 deletions example/ec_256k_private.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEINCRiJnNDnzfo2So2tWY4AIuzeC2ZBp/hmMDcZz3Fh45oAcGBSuBBAAK
oUQDQgAE0aELkvG/Xeo5y6o0WXRAjlediLptGz7Q8zjDmpGFXkKBYZ6IiL7JJ2Tk
cHzd83bmeUeGX33RGTYFPXs5t/VBnw==
-----END EC PRIVATE KEY-----
4 changes: 4 additions & 0 deletions example/ec_256k_public.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0aELkvG/Xeo5y6o0WXRAjlediLptGz7Q
8zjDmpGFXkKBYZ6IiL7JJ2TkcHzd83bmeUeGX33RGTYFPXs5t/VBnw==
-----END PUBLIC KEY-----
100 changes: 97 additions & 3 deletions example/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@ void main() {
rs256();
print('-----------------------\n');

print('----- ECDSA SHA-256 -----');
print('----- ECDSA P-256 -----');
es256();
print('-------------------------');
print('-----------------------\n');

print('----- ECDSA secp256k -----');
es256k();
print('--------------------------\n');

print('----- RSA-PSS SHA-256 -----');
ps256();
print('---------------------------\n');
}

// HMAC SHA-256 algorithm
Expand Down Expand Up @@ -96,7 +104,7 @@ void rs256() {
}
}

// ECDSA SHA-256 algorithm
// ECDSA P-256 algorithm
void es256() {
String token;

Expand Down Expand Up @@ -138,3 +146,89 @@ void es256() {
}
}
}

// ECDSA secp256k algorithm
void es256k() {
String token;

/* Sign */ {
// Create a json web token
final jwt = JWT(
{
'id': 123,
'server': {
'id': '3e4fc296',
'loc': 'euw-2',
}
},
issuer: 'https://github.com/jonasroussel/dart_jsonwebtoken',
);

// Sign it
final pem = File('./example/ec_256k_private.pem').readAsStringSync();
final key = ECPrivateKey(pem);

token = jwt.sign(key, algorithm: JWTAlgorithm.ES256K);

print('Signed token: $token\n');
}

/* Verify */ {
try {
// Verify a token
final pem = File('./example/ec_256k_public.pem').readAsStringSync();
final key = ECPublicKey(pem);

final jwt = JWT.verify(token, key);

print('Payload: ${jwt.payload}');
} on JWTExpiredException {
print('jwt expired');
} on JWTException catch (ex) {
print(ex.message); // ex: invalid signature
}
}
}

// RSA-PSS SHA-256 algorithm
void ps256() {
String token;

/* Sign */ {
// Create a json web token
final jwt = JWT(
{
'id': 123,
'server': {
'id': '3e4fc296',
'loc': 'euw-2',
}
},
issuer: 'https://github.com/jonasroussel/dart_jsonwebtoken',
);

// Sign it
final pem = File('./example/rsa_pss_private.pem').readAsStringSync();
final key = RSAPrivateKey(pem);

token = jwt.sign(key, algorithm: JWTAlgorithm.PS256);

print('Signed token: $token\n');
}

/* Verify */ {
try {
// Verify a token
final pem = File('./example/rsa_pss_public.pem').readAsStringSync();
final key = RSAPublicKey(pem);

final jwt = JWT.verify(token, key);

print('Payload: ${jwt.payload}');
} on JWTExpiredException {
print('jwt expired');
} on JWTException catch (ex) {
print(ex.message); // ex: invalid signature
}
}
}
29 changes: 29 additions & 0 deletions example/rsa_pss_private.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-----BEGIN PRIVATE KEY-----
MIIE7QIBADA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3
DQEBCDALBglghkgBZQMEAgGiAwIBIASCBKcwggSjAgEAAoIBAQC5dJxueDHgMQ3j
NL0MGpCXunskqPwJNhqE82vLKgnu1uEVie1NWwha+VpB9OPAS2B1YapiI1oFw2dM
P+jkZDP2CbuiPhZjbAcxXky5eVYiTusPDmJjHxwP3AeO7F3Ht2FQih3kT1vNOCRZ
oAM2vHh7q1iETxQAuIrgooYmd35IOPjFQ7s/9iXZSHfW6FIj6WFMx1XrDVknkHIA
KTvrYWl44oIuTygK/3vovWM9Tyh7lLAsYWt7PT8jyDmJdkEQEYty7LR4gvommcZq
5JGl8q+rk05+vD1506t5EtVyp0iVJyMfFAHeaU0bugnS6gXvWlfaGS3vngvY9SQ2
AsZ1HnQvAgMBAAECggEAFai+1FAJUyuneY+hPJalqHLJCwEJXnIJKtnbDwE7478I
zqErK8uj8CwLFITrTHwBKfRcF9YVH3Mwz0DvjCz/vI5qcYpaxwXI2UUwJME9BAi/
fySo7PanKlsCLvkAAuEx5lwbHZz/Fbqm1CjR90SPtbHPRrSNm3/yCEYy8K8n+nsp
9j87y/oP1HEL7rsaz2KTQzMCnZX1BiEGK26hkzzG5UZ0pBJEABvR6Nvj5Xx+B1xL
3aFuK/zeaZKIwdJ6yHZ4tK8A60e3uxHifNcGFfoAbLzg0U1J3RWoEdnCBUDxAwZQ
ebBH18CdXz+7MYvwFcjIJrK/HP8HVLlkDz1d91wnkQKBgQDhRKGLhxT/LibjdUKe
OIb+23bbGLKj2/hrbMqB44s/oYxjdZkIL5a9n85s1L0wgViAeLqDV5EeyCsm1vB5
YYyV9V5xMuIyQuHd34s6tce7ZhuJQgYAUMB1YkMuXtvvnE4lBUxwZesZDE1hFbQj
W8mVvSH7LU0dnqBrlPc0TVNiPQKBgQDSwYv5923mkWo2ia57LX7K3s8ueglHYxJc
/H/OGlqsnY/8QQJhVTpAgMvAYTLuA+x5wUE8YJPDj/WPxoyVNnicjQSLCfAmLrfs
VT+wRh9eRbEc3HL46r8nqBvZJX0j/mwbd3i3iCFzrh/8HLIvT+hS0gPqDgjPEF1k
HzmNlRey2wKBgQCLykgpSqlH9X7iddjiUJfNPamTKs9oic+t8jP0yJyX3ws8iTRu
9QEpKSszNA03NX0TNFghu0xt+q90ibtux48zW7HAs1/U6tY5FkjTJQ0OCL4bviH1
PidAcLrZ4rm/BpMjvBcEROrQf2bhUVOZAZOl3VliAmmxcMeCG04QYc/VzQKBgG+m
h2A6W2d9e9Y+pEevN2+EECAgGJBQBOdsAM0QGx89LY1GZ1tnCkAnu0lEdPWw8HMk
FUpGI6HDvySW290kiUruTgzWi/m+YEN8egwJag7IPub6RpJl0jTRE0e7W4tY+q6m
YTZhkM823Mzz6tWzsHFHvzkcjEAd/EvRWu0NogtnAoGABK2GucOgxdyd2W0QJloX
2y7l5W6ymIrbpSKeaDFXas/NVtls6nDseKzUTQf9RfFVXa1FEkvrRZE/Yl4sn/Xs
1tDERXraeKfcQ6A9uokEMflgBqnp8AcsBGVFfuw7xJAmF7fKwJqwOyFc8BK4nkZ8
vwWmPat2rQ7MRvKeTY11kT4=
-----END PRIVATE KEY-----
10 changes: 10 additions & 0 deletions example/rsa_pss_public.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-----BEGIN PUBLIC KEY-----
MIIBUjA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3DQEB
CDALBglghkgBZQMEAgGiAwIBIAOCAQ8AMIIBCgKCAQEAuXScbngx4DEN4zS9DBqQ
l7p7JKj8CTYahPNryyoJ7tbhFYntTVsIWvlaQfTjwEtgdWGqYiNaBcNnTD/o5GQz
9gm7oj4WY2wHMV5MuXlWIk7rDw5iYx8cD9wHjuxdx7dhUIod5E9bzTgkWaADNrx4
e6tYhE8UALiK4KKGJnd+SDj4xUO7P/Yl2Uh31uhSI+lhTMdV6w1ZJ5ByACk762Fp
eOKCLk8oCv976L1jPU8oe5SwLGFrez0/I8g5iXZBEBGLcuy0eIL6JpnGauSRpfKv
q5NOfrw9edOreRLVcqdIlScjHxQB3mlNG7oJ0uoF71pX2hkt754L2PUkNgLGdR50
LwIDAQAB
-----END PUBLIC KEY-----
Loading

0 comments on commit 3847ffc

Please sign in to comment.