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.'),
          ],
        ),
      ),
    );
  }
}

注意事项

  1. 替换示例数据

    • signedJsonString中的签名JSON字符串需要替换为你的实际签名JSON。
    • secretKey需要替换为你的实际密钥。
  2. 算法

    • 示例中使用了HS256算法。如果你使用的是其他算法,比如RS256,你需要确保你的密钥和算法匹配,并相应地调整代码。
  3. 错误处理

    • 示例中的错误处理较为简单,你可能需要根据具体需求进行更详细的错误处理。
  4. 依赖项版本

    • 确保signed_json插件的版本是最新的,并且与你的Flutter SDK版本兼容。

这样,你就可以在Flutter应用中验证签名的JSON对象了。

回到顶部