Flutter加密解密插件jose2的使用
Flutter 加密解密插件 jose2 的使用
本指南将详细介绍如何在 Flutter 中使用 jose2
插件进行 JSON Web 签名(JWS)、JSON Web 加密(JWE)、JSON Web 密钥(JWK)和 JSON Web 令牌(JWT)的操作。
支持的 JSON Web 算法
该库支持标准定义中的许多算法。
签名算法(用于 JWS)
- HS256 HMAC 使用 SHA-256
- HS384 HMAC 使用 SHA-384
- HS512 HMAC 使用 SHA-512
- RS256 RSASSA-PKCS1-v1_5 使用 SHA-256
- RS384 RSASSA-PKCS1-v1_5 使用 SHA-384
- RS512 RSASSA-PKCS1-v1_5 使用 SHA-512
- ES256 ECDSA 使用 P-256 和 SHA-256
- ES256K ECDSA 使用 P-256K 和 SHA-256
- ES384 ECDSA 使用 P-384 和 SHA-384
- ES512 ECDSA 使用 P-521 和 SHA-512
- none 无数字签名或 MAC
密钥包装算法(用于 JWE)
- RSA1_5 RSAES-PKCS1-v1_5
- RSA-OAEP RSAES OAEP 使用默认参数
- RSA-OAEP-256 RSAES OAEP 使用 SHA-256 和 MGF1 使用 SHA-256
- A128KW AES 密钥包装使用 128 位密钥
- A192KW AES 密钥包装使用 192 位密钥
- A256KW AES 密钥包装使用 256 位密钥
- dir 直接使用共享对称密钥作为 CEK
加密算法(用于 JWE)
- A128CBC-HS256 AES_128_CBC_HMAC_SHA_256 身份验证加密算法
- A192CBC-HS384 AES_192_CBC_HMAC_SHA_384 身份验证加密算法
- A256CBC-HS512 AES_256_CBC_HMAC_SHA_512 身份验证加密算法
- A128GCM AES GCM 使用 128 位密钥
- A192GCM AES GCM 使用 192 位密钥
- A256GCM AES GCM 使用 256 位密钥
使用方法
解码并验证 JWS
main() async {
var encoded = "eyJhbGciOiJFUzUxMiJ9."
"UGF5bG9hZA."
"AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZq"
"wqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8Kp"
"EHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn";
// 从编码字符串创建 JsonWebSignature
var jws = JsonWebSignature.fromCompactSerialization(encoded);
// 提取载荷
var payload = jws.unverifiedPayload;
print("内容为: ${payload.stringContent}");
print("保护参数: ${payload.protectedHeader.toJson()}");
// 创建 JsonWebKey 以验证签名
var jwk = new JsonWebKey.fromJson({
"kty": "EC",
"crv": "P-521",
"x": "AekpBQ8ST8a8VcfVOTNl353vSrDCLLJXmPk06wTjxrrjcBpXp5EOnYG_"
"NjFZ6OvLFV1jSfS9tsz4qUxcWceqwQGk",
"y": "ADSmRA43Z1DSNx_RvcLI87cdL07l6jQyyBXMoxVg_l2Th-x3S1WDhjDl"
"y79ajL4Kkd0AZMaZmh9ubmf63e3kyMj2",
"d": "AY5pb7A0UFiB3RELSD64fTLOSV_jazdF7fLYyuTw8lOfRhWg6Y6rUrPA"
"xerEzgdRhajnu0ferB0d53vM9mE15j2C"
});
var keyStore = new JsonWebKeyStore()..addKey(jwk);
// 验证签名
var verified = await jws.verify(keyStore);
print("签名验证结果: $verified");
}
创建 JWS
main() async {
// 创建一个 builder
var builder = new JsonWebSignatureBuilder();
// 设置内容
builder.stringContent = "It is me";
// 设置一些保护头
builder.setProtectedHeader("createdAt", new DateTime.now().toIso8601String());
// 添加一个用于签名的密钥,可以添加多个密钥以供不同接收者使用
builder.addRecipient(
new JsonWebKey.fromJson({
"kty": "oct",
"k":
"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
}),
algorithm: "HS256");
// 构建 JWS
var jws = builder.build();
// 输出紧凑序列化
print("JWS 紧凑序列化: ${jws.toCompactSerialization()}");
// 输出 JSON 序列化
print("JWS JSON 序列化: ${jws.toJson()}");
}
解码并解密 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";
// 从编码字符串创建 JsonWebEncryption
var jwe = JsonWebEncryption.fromCompactSerialization(encoded);
// 创建用于解密签名的 JsonWebKey
var jwk = new JsonWebKey.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 = new JsonWebKeyStore()..addKey(jwk);
// 解密载荷
var payload = await jwe.getPayload(keyStore);
print("解密后的内容: ${payload.stringContent}");
}
创建 JWE
main() async {
// 创建一个 builder
var builder = new JsonWebEncryptionBuilder();
// 设置内容
builder.stringContent = "这是我的最大秘密";
// 设置一些保护头
builder.setProtectedHeader("createdAt", new DateTime.now().toIso8601String());
// 添加一个用于加密内容加密密钥的密钥
var jwk = new JsonWebKey.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");
// 设置要使用的内容加密算法
builder.encryptionAlgorithm = "A128CBC-HS256";
// 构建 JWE
var jwe = builder.build();
// 输出紧凑序列化
print("JWE 紧凑序列化: ${jwe.toCompactSerialization()}");
// 输出 JSON 序列化
print("JWE JSON 序列化: ${jwe.toJson()}");
}
解码、验证和验证 JWT
main() async {
var encoded = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9."
"eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt"
"cGxlLmNvbS9pc19yb290Ijp0cnVlfQ."
"dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk";
// 解码 JWT,注意:此构造函数只能用于 JWS 结构内的 JWT
var jwt = new JsonWebToken.unverified(encoded);
// 输出声明
print("声明: ${jwt.claims}");
// 创建 Key Store 以验证签名
var keyStore = new JsonWebKeyStore()
..addKey(new JsonWebKey.fromJson({
"kty": "oct",
"k":
"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
}));
var verified = await jwt.verify(keyStore);
print("验证结果: $verified");
// 另外,一起创建并验证 JsonWebToken,这同样适用于 JWE 内的 JWT
jwt = await JsonWebToken.decodeAndVerify(encoded, keyStore);
// 验证声明
var violations = jwt.claims.validate(issuer: Uri.parse("alice"));
print("违反: $violations");
}
创建 JWT
main() async {
var claims = new JsonWebTokenClaims.fromJson({
"exp": new Duration(hours: 4).inSeconds,
"iss": "alice",
});
// 创建一个 builder,解码 JWT 在 JWS 中,所以使用 JsonWebSignatureBuilder
var builder = new JsonWebSignatureBuilder();
// 设置内容
builder.jsonContent = claims.toJson();
// 添加一个用于签名的密钥,只能添加一个用于 JWT
builder.addRecipient(
new JsonWebKey.fromJson({
"kty": "oct",
"k":
"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"
}),
algorithm: "HS256");
// 构建 JWS
var jws = builder.build();
// 输出紧凑序列化
print("JWT 紧凑序列化: ${jws.toCompactSerialization()}");
}
更多关于Flutter加密解密插件jose2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter加密解密插件jose2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用jose2
插件进行加密和解密的示例代码。jose2
是一个用于处理JSON Web Tokens (JWT)、JSON Web Encryption (JWE) 和 JSON Web Signatures (JWS) 的Flutter插件。
首先,确保你已经在pubspec.yaml
文件中添加了jose2
依赖:
dependencies:
flutter:
sdk: flutter
jose2: ^0.5.0 # 请检查最新版本号并替换
然后运行flutter pub get
来安装依赖。
接下来,下面是一个示例代码,展示如何使用jose2
进行加密和解密操作。这个示例假设你使用对称密钥(例如AES)进行加密和解密。
import 'package:flutter/material.dart';
import 'package:jose2/jose2.dart';
import 'dart:typed_data';
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String? decryptedMessage;
@override
void initState() {
super.initState();
_performEncryptionAndDecryption();
}
Future<void> _performEncryptionAndDecryption() async {
// 对称密钥(请确保在实际应用中安全存储密钥)
final Uint8List key = Uint8List.fromList(List.generate(32, (i) => i % 256));
// 要加密的消息
final String plainTextMessage = "Hello, Flutter and JOSE!";
final Uint8List plainTextBytes = Uint8List.fromList(utf8.encode(plainTextMessage));
// 创建JWE加密器
final jweEncryptor = JweEncryptor(
alg: 'dir',
enc: 'A256GCM',
key: key,
);
// 加密消息
final jweEncrypted = await jweEncryptor.encrypt(plainTextBytes);
print("Encrypted message: ${base64Url.encode(jweEncrypted)}");
// 创建JWE解密器
final jweDecryptor = JweDecryptor(
alg: 'dir',
enc: 'A256GCM',
key: key,
);
// 解密消息
final jweDecryptedBytes = await jweDecryptor.decrypt(jweEncrypted);
final decryptedMessage = utf8.decode(jweDecryptedBytes);
// 更新UI
setState(() {
this.decryptedMessage = decryptedMessage;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('JOSE2 Encryption/Decryption Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
decryptedMessage ?? 'Decrypting...',
style: TextStyle(fontSize: 24),
),
],
),
),
),
);
}
}
代码说明:
- 依赖导入:导入
jose2
和其他必要的包。 - 密钥生成:生成一个32字节的对称密钥(AES-256需要32字节的密钥)。在实际应用中,密钥应该从安全存储中加载。
- 消息加密:将要加密的消息转换为字节数组,然后使用
JweEncryptor
进行加密。 - 消息解密:使用
JweDecryptor
对加密后的消息进行解密,并将结果转换回字符串。 - UI更新:在Flutter UI中显示解密后的消息。
注意事项:
- 密钥管理:在实际应用中,密钥管理非常重要。密钥应存储在安全的地方,例如Android的KeyStore或iOS的Keychain。
- 异常处理:在实际应用中,应添加异常处理来捕获并处理加密和解密过程中可能发生的错误。
- 最新版本:确保使用
jose2
插件的最新版本,并查阅其文档以获取最新的API和用法。
希望这个示例能帮助你在Flutter项目中使用jose2
进行加密和解密操作。