Package selection guidance compiled from public package information, community data, and project usage.
A Dart implementation of the JOSE (Javascript Object Signing and Encryption) standards, enabling secure handling of JWE (encrypted data), JWS (signed data), JWK (key management), and JWT (tokens). This library supports cross-platform applications on Android, iOS, Web, macOS, Windows, and Linux, providing robust cryptographic operations for authentication, authorization, and secure data exchange. It is ideal for developers integrating token-based security into Flutter apps.
Use cases
Secure token handling in authentication flows
Encrypting sensitive data with JWE
Verifying signed tokens with JWS
Managing cryptographic keys via JWK
Implementing OAuth2 and OpenID Connect
Securing API communications
Key features
Supports JWE, JWS, JWK, and JWT standards
Cross-platform compatibility
Lightweight and efficient
Comprehensive cryptographic algorithms
Easy integration with Flutter apps
Well-documented and actively maintained
Suitable for
Flutter developers building secure apps
API clients requiring token validation
Authentication systems using JWT
Applications needing encrypted payloads
Developers working with OAuth2/OpenID Connect
Considerations
Requires understanding of JOSE standards
May need additional dependency management
Not suitable for low-level crypto primitives
Best used with proper key storage practices
Limited to high-level JOSE operations only
Original README
Original README snapshot from the linked source repository. Visit the repository for the latest content.
main() async {
var encoded = "eyJhbGciOiJFUzUxMiJ9.""UGF5bG9hZA.""AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZq""wqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8Kp""EHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn";
// create a JsonWebSignature from the encoded stringvar jws = JsonWebSignature.fromCompactSerialization(encoded);
// extract the payloadvar payload = jws.unverifiedPayload;
print("content of jws: ${payload.stringContent}");
print("protected parameters: ${payload.protectedHeader.toJson()}");
// create a JsonWebKey for verifying the signaturevar jwk = newJsonWebKey.fromJson({
"kty": "EC",
"crv": "P-521",
"x": "AekpBQ8ST8a8VcfVOTNl353vSrDCLLJXmPk06wTjxrrjcBpXp5EOnYG_""NjFZ6OvLFV1jSfS9tsz4qUxcWceqwQGk",
"y": "ADSmRA43Z1DSNx_RvcLI87cdL07l6jQyyBXMoxVg_l2Th-x3S1WDhjDl""y79ajL4Kkd0AZMaZmh9ubmf63e3kyMj2",
"d": "AY5pb7A0UFiB3RELSD64fTLOSV_jazdF7fLYyuTw8lOfRhWg6Y6rUrPA""xerEzgdRhajnu0ferB0d53vM9mE15j2C"
});
var keyStore = newJsonWebKeyStore()..addKey(jwk);
// verify the signaturevar verified = await jws.verify(keyStore);
print("signature verified: $verified");
}
Create a JWS
main() async {
// create a buildervar builder = newJsonWebSignatureBuilder();
// set the content
builder.stringContent = "It is me";
// set some protected header
builder.setProtectedHeader("createdAt", newDateTime.now().toIso8601String());
// add a key to sign, you can add multiple keys for different recipients
builder.addRecipient(
newJsonWebKey.fromJson({
"kty": "oct",
"k":
"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
}),
algorithm: "HS256");
// build the jwsvar jws = builder.build();
// output the compact serializationprint("jws compact serialization: ${jws.toCompactSerialization()}");
// output the json serializationprint("jws json serialization: ${jws.toJson()}");
}
Decode and decrypt a JWE
main() async {
var encoded = "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.""UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm""1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7Pc""HALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIF""NPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8""rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv""-B3oWh2TbqmScqXMR4gp_A.""AxY8DCtDaGlsbGljb3RoZQ.""KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.""9hH0vgRfYgPnAHOd8stkvw";
// create a JsonWebEncryption from the encoded stringvar jwe = JsonWebEncryption.fromCompactSerialization(encoded);
// create a JsonWebKey for decrypting the signaturevar jwk = newJsonWebKey.fromJson(
{
"kty": "RSA",
"n": "sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl""UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre""cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_""7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI""Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU""7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw",
"e": "AQAB",
"d": "VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq""1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-ry""nq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_""0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj""-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-Kyvj""T1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ",
"p": "9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68""ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEP""krdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM",
"q": "uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-y""BhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN""-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0",
"dp": "w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuv""ngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcra""Hawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs",
"dq": "o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff""7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_""odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU",
"qi": "eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlC""tUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZ""B9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo"
},
);
var keyStore = newJsonWebKeyStore()..addKey(jwk);
// decrypt the payloadvar payload = await jwe.getPayload(keyStore);
print("decrypted content: ${payload.stringContent}");
}
Create a JWE
main() async {
// create a buildervar builder = newJsonWebEncryptionBuilder();
// set the content
builder.stringContent = "This is my bigest secret";
// set some protected header
builder.setProtectedHeader("createdAt", newDateTime.now().toIso8601String());
// add a key to encrypt the Content Encryption Keyvar jwk = newJsonWebKey.fromJson(
{
"kty": "RSA",
"n": "sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl""UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre""cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_""7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI""Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU""7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw",
"e": "AQAB",
"d": "VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq""1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-ry""nq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_""0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj""-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-Kyvj""T1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ",
"p": "9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68""ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEP""krdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM",
"q": "uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-y""BhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN""-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0",
"dp": "w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuv""ngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcra""Hawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs",
"dq": "o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff""7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_""odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU",
"qi": "eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlC""tUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZ""B9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo"
},
);
builder.addRecipient(jwk, algorithm: "RSA1_5");
// set the content encryption algorithm to use
builder.encryptionAlgorithm = "A128CBC-HS256";
// build the jwsvar jwe = builder.build();
// output the compact serializationprint("jwe compact serialization: ${jwe.toCompactSerialization()}");
// output the json serializationprint("jwe json serialization: ${jwe.toJson()}");
}
Decode and verify and validate a JWT
main() async {
var encoded = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.""eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt""cGxlLmNvbS9pc19yb290Ijp0cnVlfQ.""dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk";
// decode the jwt, note: this constructor can only be used for JWT inside JWS// structuresvar jwt = newJsonWebToken.unverified(encoded);
// output the claimsprint("claims: ${jwt.claims}");
// create key store to verify the signaturevar keyStore = newJsonWebKeyStore()
..addKey(newJsonWebKey.fromJson({
"kty": "oct",
"k":
"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
}));
var verified = await jwt.verify(keyStore);
print("verified: $verified");
// alternatively, create and verify the JsonWebToken together, this is also// applicable for JWT inside JWE
jwt = awaitJsonWebToken.decodeAndVerify(encoded, keyStore);
// validate the claimsvar violations = jwt.claims.validate(issuer: Uri.parse("alice"));
print("violations: $violations");
}
Create a JWT
main() async {
var claims = newJsonWebTokenClaims.fromJson({
"exp": newDuration(hours: 4).inSeconds,
"iss": "alice",
});
// create a builder, decoding the JWT in a JWS, so using a// JsonWebSignatureBuildervar builder = newJsonWebSignatureBuilder();
// set the content
builder.jsonContent = claims.toJson();
// add a key to sign, can only add one for JWT
builder.addRecipient(
newJsonWebKey.fromJson({
"kty": "oct",
"k":
"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
}),
algorithm: "HS256");
// build the jwsvar jws = builder.build();
// output the compact serializationprint("jwt compact serialization: ${jws.toCompactSerialization()}");
}
Features and bugs
Please file feature requests and bugs at the issue tracker.
Sponsor
Creating and maintaining this package takes a lot of time. If you like the result, please consider to :heart: sponsor.
With your support, I will be able to further improve and support this project.
Also, check out my other dart packages at pub.dev.