Flutter签名验证插件signed_json的使用
Flutter签名验证插件signed_json的使用
签名验证插件signed_json
此库用于验证由sign_config
生成的文件。
如何使用它
验证
获取签名密钥
访问 https://mkjwk.org 并选择EC类型:
- 密钥大小: P-512
- 密钥用途: 签名
- 算法: ES512: 使用P-521和SHA-512的ECDSA
- 密钥ID: 指定为
signed_json
- 显示X.509: 否
复制私钥。
获取验证密钥
复制公钥。
解密
获取加密密钥
访问 https://mkjwk.org 并选择RSA类型:
- 密钥大小: 2048
- 密钥用途: 签名
- 算法: PS512
- 密钥ID: 指定为
signed_json
- 显示X.509: 否
移除使用/ kid/ alg
复制。
获取解密密钥
复制加密密钥。
完整示例代码
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:signed_json/signed_json.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
static const verifyCert = '''
{
"kty": "EC",
"use": "sig",
"crv": "P-521",
"kid": "signed_json",
"x": "AT0MMaUvyZdRZaCIqkLZPks0NE4kPZhgTwIivnr0tDhcl7Ao9SSdiXPuCsZS3HaAuQq5Kk1sSWGwNtteiq5JsiSg",
"y": "AVKxKaIYJewNWA3DvD5qzpW9vSMt6A1crUqVpQ-MKAOVsCL_RwwvQoedRoMbYpf6T7XLflECaI58pBtv8JfF8zVb",
"alg": "ES512"
}''';
static const decryptCert = '''
{
"p": "9MtlbJu1GqQ44CZnauptbxR8LMRqja0gh-2LLajHcGuaayegcTnSyMI33ecZo3k4aaIsbglKOFM93dNDMIkbMjsUAs3aLUMWh5rZblJqoS1eBk02mLe9ybgpO6Vaof9aCIWovR59MotSAFeWsA1QTi_ZgUdHmVpak-hsEkZFo5s",
"kty": "RSA",
"q": "7482MJG7HhOYyzh6Z0Ri6993TNUSApjaOHyAAlAreCNpG8_0IOiPzdnHihVtYJBskF5zJw1XWEv-efv-INP1fojkApPtZKwPgxDGwf2Ynie4Hm2kD7iF2ShHAwHcGGQJpEmqcLgqV6wtAJyRwtN_F-IajRfb_wOUHH8laNYpDns",
"d": "W98NsqYBgYax7OCeYXMfrAH_y7IcGfQf37iodfyVVS7LNMIJxFD_L3Ch4ZurRmp8cY3KQfsUJPFtdwOVWjWR-TqCWptGlRAluzFYu6Dw_C00YEEOPYhwlzf7FEtg1sDTanTHxvqs1B2lNfgXpXgEzwJVFkpUzmxBR96KrQY_L-qFe0ODHdHiZBr1veRTmo4dd_exrrn8tXO8CzIUkMJaofxDnqOQb98MDaAoncjawWlFgFcGLQyC9a0d2xLxVMyQ4cIZS1FTP_i-utOFKBLAM2PmyXmeVyliZn7dqJWa9Jh-6HFXaFWuUrkRglTKz73QvvEVspU_xLpcR9Tz_bufMQ",
"e": "AQAB",
"qi": "a2H0BBAKe43HJiHeiv0vQjZxvIlFKqdZhgzjqzE7cqzWyYNTD00s2Zaaqv-upVFZqp3hyNU9EL_SS9oOVccS6IXrmXLAh0PP7UYYRrXa1uwG9dNm-FRXiDUUR9C38i2plhxaLzj9Wfzb74y9gY4oEf3AzYav59i02ujLggjhXXM",
"dp": "bDSQI578Qcd_oI05P4haUTSD4yH7W57Ad3UoBUnKxsW5n04H3KTLqJQ5L6xcp-cIaaEW9JjEpvscqLYeyBCC5gQ5RzgJDeLOzahEHkDuA0rTegOdc4ocqVLvXv8rfdoqyQOT3-zfOH1fBOmyoSVxbu41vbBtVLscuK6PPtCzLas",
"dq": "pqK0rBZC1YoGJ54yrrCIKtC3uI8hxwKyEMaxeGpxwlDHZVxC0b1TgnoxbaC4A4qSqd25Nfn2vumlqw6ZWBZ4Vrs793sUj4mMBLxftUMErUatsSTNEU5mdIaq1rGtep3jgw7m6x9__Jo8d4dxcNcTOfbCR1DIa9v-Y9AhoooN5w8",
"n": "5RLVH2XrHQbGBlYNp-OmEvNMJHv3PB20YQNkJopqODga1qM5XuRpgWGa9kZ8TLpAjjjq186o2Uo9j0M_NYTuGyi_QsqtNx1dBx7a17GU1aJFFrAogPEPdqLLGKVkaxNiP21hPU52MKUfFeheGfGHh3PJipJcQyz-rTXTxvkRPbI7_YFg9bKcHzrCj0Ad1Jn3-m36dfPjwdWtWlMucRaM0DhzAmcsre5zW6Ot79dQzyDRHHH8Xp1bgM820CizG_urQYYia5V0anQ4SYx5qyMUYaHfM42iVF3o7IcxcNHbzC8TUf78sEBc_T8S_GaZfeYxy2CaMUYixM4XFUKCWDsVeQ"
}''';
static const encoded =
'eyJhbGciOiJFUzUxMiIsImtpZCI6InNpZ25lZF9qc29uIn0.eNqr5lJQUCrOz02NL0mtKFGyUlAKBnJKMjLz0hXgLCWuWgALBg2D.AXMx-2iQVtaDIaV14lXhw7j6hW0D0HKyWYu9kUz1W4W0j8gOlDU2YWipyEDWGAGXKgdmIpWl1SeWrVlXdJeVLYFlAe2pqriYxevIzEErRdP1VwLDP7lCiLERCaiz_usAAY2fiHVNqEqFhPr8bxpnWIxiEcoG2BB5zUEoEH_kZ51I0jgV';
static const encryptedEncoded =
'eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiUlNBMV81In0.a5a73YZgaQwTH3V5pqMXUIuAxKUqZdH5rQxN9RBWNiizJK03BamKqOZjbHuWv18qwAkgWxudRXF4io2vVZv5gChmpwQ3KjzS2z4ccMY5GNnf-_5SSX2bzIvoEJvBaFvseA049cBsdvcfTKKZZXJXe_z4k_iB-hyvo5JOQ8ki30sToDeMT9sVkLfh9icMP-DJ73zzqmsK9twpZgjChmEdHqJbx5xmejfSjdW76-RTWm3LEFkTBsg_Ye3Lupj9qmAkIQvC9Xgbvu2tCcmgSLpQz135H33GSP_cYnRfX0ho-nXPOpvba4ASJL68S_BBmrpCTG2U1w95RKufqVhwKKZUQg.tSsXy0GVk6CsJnnkbjO-nQ.KPFLPN8tLK3vqAvLvLO9IO6Q88vPVPNO1YoiP3tsaP_sbNTa92W514eakZ0QiaNU.5TWtnlE_Bbx4xo95mRoITw';
final _signedJson = SignedJson(verifyCert, decryptionCert: decryptCert);
String? _error;
var _data = '';
var _encryptedData = '';
[@override](/user/override)
void initState() {
super.initState();
_getData();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('签名测试应用'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_error == null) ...[
Text(
_data,
textAlign: TextAlign.center,
),
Text(
_encryptedData,
textAlign: TextAlign.center,
),
] else ...[
Text(
_error ?? '',
textAlign: TextAlign.center,
),
]
],
),
),
),
);
}
Future<void> _getData() async {
try {
final data = await _signedJson.verify<Map<String, dynamic>>(encoded);
final encryptedData =
await _signedJson.decrypt<Map<String, dynamic>>(encryptedEncoded);
_data = jsonEncode(data);
_encryptedData = jsonEncode(encryptedData);
} catch (e, stack) {
print(stack); // 忽略打印
_error = e.toString();
}
setState(() {});
}
}
更多关于Flutter签名验证插件signed_json的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter签名验证插件signed_json的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用signed_json
插件进行签名验证的示例代码。signed_json
插件通常用于验证经过JSON Web Signature (JWS)签名的JSON对象。
首先,你需要在你的pubspec.yaml
文件中添加signed_json
依赖项:
dependencies:
flutter:
sdk: flutter
signed_json: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来获取依赖项。
接下来是一个完整的Flutter应用示例,它展示了如何使用signed_json
插件来验证签名的JSON对象。
import 'package:flutter/material.dart';
import 'package:signed_json/signed_json.dart';
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Signed JSON Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String? resultText;
void _verifySignedJson() async {
// 这是一个示例签名JSON字符串,你需要替换为你的实际数据
const signedJsonString = '''
{
"header": {"alg": "HS256"},
"payload": "{\"message\":\"Hello, World!\"}",
"signature": "your_signature_here"
}
''';
// 将字符串解析为Map
final Map<String, dynamic> signedJsonMap = jsonDecode(signedJsonString);
// 从Map中提取header, payload, 和signature
final Map<String, String> header = Map<String, String>.from(signedJsonMap['header']);
final String payloadString = signedJsonMap['payload'];
final String signature = signedJsonMap['signature'];
// 将payload转换为字节
final Uint8List payloadBytes = Uint8List.fromList(payloadString.codeUnits);
// 假设你有一个密钥用于验证签名
final String secretKey = 'your_secret_key_here'; // 请替换为你的实际密钥
try {
// 使用HS256算法验证签名
final bool isValid = await verifyJws(
header: header,
payload: payloadBytes,
signature: signature,
secretKey: secretKey,
algorithm: 'HS256'
);
// 更新状态以显示结果
setState(() {
resultText = isValid ? 'Signature is valid' : 'Signature is invalid';
});
} catch (e) {
// 处理错误
setState(() {
resultText = 'Error verifying signature: ${e.toString()}';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Signed JSON Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _verifySignedJson,
child: Text('Verify Signed JSON'),
),
Text(resultText ?? 'Press the button to verify the signature.'),
],
),
),
);
}
}
注意事项
-
替换示例数据:
signedJsonString
中的签名JSON字符串需要替换为你的实际签名JSON。secretKey
需要替换为你的实际密钥。
-
算法:
- 示例中使用了
HS256
算法。如果你使用的是其他算法,比如RS256
,你需要确保你的密钥和算法匹配,并相应地调整代码。
- 示例中使用了
-
错误处理:
- 示例中的错误处理较为简单,你可能需要根据具体需求进行更详细的错误处理。
-
依赖项版本:
- 确保
signed_json
插件的版本是最新的,并且与你的Flutter SDK版本兼容。
- 确保
这样,你就可以在Flutter应用中验证签名的JSON对象了。