Flutter数据处理与分析插件at_chops的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter数据处理与分析插件at_chops的使用

特性

  • 使用RSA进行非对称公钥/私钥加密/解密
  • 使用AES进行对称密钥加密/解密
  • 用于PKAM认证的数据摘要签名和验证
  • 用于at协议中公共数据的签名和验证
  • 哈希操作

开始使用

  • 开发者应该具备基本的非对称和对称加密知识。
  • 开发者可以使用自己的密钥对/密钥,或者通过AtChopsUtil创建新的密钥对/密钥。

使用示例

import 'dart:io';
import 'dart:convert';
import 'dart:typed_data';

import 'package:at_chops/at_chops.dart';
import 'package:at_chops/src/algorithm/at_algorithm.dart';
import 'package:encrypt/encrypt.dart';

/// 使用新生成的密钥对
/// dart run at_chops_example.dart
/// 或者
/// 使用来自atKeys文件的密钥对
/// dart run at_chops_example.dart <path_to_atkeys_file>
void main(List<String> args) async {
  AtChops atChops;

  if (args.isNotEmpty) {
    var atKeysFilePath = args[0];
    if (!File(atKeysFilePath).existsSync()) {
      throw Exception('\n无法找到.atKeys文件: $atKeysFilePath');
    }
    String atAuthData = await File(atKeysFilePath).readAsString();
    Map<String, String> atKeysDataMap = {};
    json.decode(atAuthData).forEach((String key, dynamic value) {
      atKeysDataMap[key] = value.toString();
    });
    atChops = _createAtChops(atKeysDataMap);
  } else {
    final atEncryptionKeyPair = AtChopsUtil.generateAtEncryptionKeyPair(); // 使用您的自己的加密密钥对
    final atPkamKeyPair = AtChopsUtil.generateAtPkamKeyPair(); // 使用您的自己的签名密钥对
    // 使用加密和pkam密钥对创建AtChopsKeys实例
    final atChopsKeys = AtChopsKeys.create(atEncryptionKeyPair, atPkamKeyPair);
    // 创建AtChopsImpl实例
    atChops = AtChopsImpl(atChopsKeys);
  }

  var atEncryptionKeyPair = atChops.atChopsKeys.atEncryptionKeyPair;
  
  // 1 - 使用非对称密钥对进行加密和解密
  final data = 'Hello World';
  // 1.1 使用[atEncryptionKeyPair.publicKey]加密数据
  final encryptionResult = atChops.encryptString(data, EncryptionKeyType.rsa2048);

  // 1.2 使用[atEncryptionKeyPair.privateKey]解密数据
  final decryptionResult = atChops.decryptString(encryptionResult.result, EncryptionKeyType.rsa2048);
  assert(data == decryptionResult.result, true);

  // 2 - 使用非对称密钥对进行签名和数据验证
  // 使用sign()和verify()
  final dataToSign = 'sample data';
  // 2.1 创建签名输入并设置签名和哈希算法类型
  AtSigningInput signingInput = AtSigningInput(dataToSign);
  signingInput.signingAlgoType = SigningAlgoType.rsa2048;
  signingInput.hashingAlgoType = HashingAlgoType.sha512;
  AtSigningAlgorithm signingAlgorithm = DefaultSigningAlgo(atEncryptionKeyPair, signingInput.hashingAlgoType);
  signingInput.signingAlgorithm = signingAlgorithm;
  // 2.2 签名数据
  final dataSigningResult = atChops.sign(signingInput);

  // 2.3 创建验证输入并设置签名和哈希算法类型
  AtSigningVerificationInput verificationInput = AtSigningVerificationInput(
      dataToSign,
      base64Decode(dataSigningResult.result),
      atEncryptionKeyPair!.atPublicKey.publicKey);
  verificationInput.signingAlgoType = SigningAlgoType.rsa2048;
  verificationInput.hashingAlgoType = HashingAlgoType.sha512;
  AtSigningAlgorithm verifyAlgorithm = DefaultSigningAlgo(atEncryptionKeyPair, verificationInput.hashingAlgoType);
  verificationInput.signingAlgorithm = verifyAlgorithm;
  // 2.4 验证签名
  AtSigningResult dataVerificationResult = atChops.verify(verificationInput);
  print('签名结果: ${dataVerificationResult.result}');
  assert(dataVerificationResult.result, true);
}

AtChops _createAtChops(Map<String, String> atKeysDataMap) {
  final atEncryptionKeyPair = AtEncryptionKeyPair.create(
      _decryptValue(atKeysDataMap[AuthKeyType.encryptionPublicKey]!, atKeysDataMap[AuthKeyType.selfEncryptionKey]!)!,
      _decryptValue(atKeysDataMap[AuthKeyType.encryptionPrivateKey]!, atKeysDataMap[AuthKeyType.selfEncryptionKey]!)!);
  final atPkamKeyPair = AtPkamKeyPair.create(
      _decryptValue(atKeysDataMap[AuthKeyType.pkamPublicKey]!, atKeysDataMap[AuthKeyType.selfEncryptionKey]!)!,
      _decryptValue(atKeysDataMap[AuthKeyType.pkamPrivateKey]!, atKeysDataMap[AuthKeyType.selfEncryptionKey]!)!);
  final atChopsKeys = AtChopsKeys.create(atEncryptionKeyPair, atPkamKeyPair);
  return AtChopsImpl(atChopsKeys);
}

class AuthKeyType {
  static const String pkamPublicKey = 'aesPkamPublicKey';
  static const String pkamPrivateKey = 'aesPkamPrivateKey';
  static const String encryptionPublicKey = 'aesEncryptPublicKey';
  static const String encryptionPrivateKey = 'aesEncryptPrivateKey';
  static const String selfEncryptionKey = 'selfEncryptionKey';
}

String? _decryptValue(String encryptedValue, String decryptionKey, {String? ivBase64}) {
  try {
    var aesKey = AES(Key.fromBase64(decryptionKey));
    var decrypter = Encrypter(aesKey);
    return decrypter.decrypt64(encryptedValue, iv: getIV(ivBase64));
  } on Exception catch (e, trace) {
    print(trace);
  } on Error catch (e) {
    print(e);
  }
  return null;
}

IV getIV(String? ivBase64) {
  if (ivBase64 == null) {
    // 从坏旧的日子,当时我们没有设置IV
    return IV(Uint8List(16));
  } else {
    return IV.fromBase64(ivBase64);
  }
}

更多关于Flutter数据处理与分析插件at_chops的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据处理与分析插件at_chops的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何使用Flutter插件at_chops进行数据处理与分析的示例代码。at_chops是一个用于处理和分析数据的Flutter插件,但需要注意的是,由于at_chops并非一个广为人知的Flutter官方或广泛使用的社区插件,我假设它具备一些基本的数据处理功能,并会提供一个假设性的代码示例。如果at_chops插件具有特定的API和功能,请参考其官方文档进行调整。

假设at_chops提供了数据过滤、排序和聚合的功能,以下是一个简单的示例代码:

1. 添加依赖

首先,在你的pubspec.yaml文件中添加at_chops依赖(请注意,这里的包名at_chops是假设的,你需要根据实际情况替换为真实的包名):

dependencies:
  flutter:
    sdk: flutter
  at_chops: ^latest_version  # 替换为实际的最新版本号

然后运行flutter pub get来获取依赖。

2. 导入插件并使用其功能

在你的Dart文件中导入at_chops插件,并使用其提供的功能进行数据处理和分析。以下是一个示例:

import 'package:flutter/material.dart';
import 'package:at_chops/at_chops.dart'; // 假设的包导入路径

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Data Processing with at_chops',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DataProcessingScreen(),
    );
  }
}

class DataProcessingScreen extends StatefulWidget {
  @override
  _DataProcessingScreenState createState() => _DataProcessingScreenState();
}

class _DataProcessingScreenState extends State<DataProcessingScreen> {
  List<Map<String, dynamic>> data = [
    {'name': 'Alice', 'age': 30, 'score': 85},
    {'name': 'Bob', 'age': 25, 'score': 90},
    {'name': 'Charlie', 'age': 35, 'score': 78},
    // 更多数据...
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Data Processing with at_chops'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Original Data:'),
            SizedBox(height: 16),
            _buildDataList(data),
            SizedBox(height: 32),
            Text('Filtered Data (age > 30):'),
            SizedBox(height: 16),
            _buildDataList(_filterData(data, (item) => item['age']! > 30)),
            SizedBox(height: 32),
            Text('Sorted Data (by score descending):'),
            SizedBox(height: 16),
            _buildDataList(_sortData(data, (a, b) => b['score']!.compareTo(a['score']!))),
          ],
        ),
      ),
    );
  }

  Widget _buildDataList(List<Map<String, dynamic>> data) {
    return ListView.builder(
      shrinkWrap: true,
      itemCount: data.length,
      itemBuilder: (context, index) {
        Map<String, dynamic> item = data[index];
        return ListTile(
          title: Text('${item['name']}: Age ${item['age']}, Score ${item['score']}'),
        );
      },
    );
  }

  List<Map<String, dynamic>> _filterData(
      List<Map<String, dynamic>> data, bool Function(Map<String, dynamic>) predicate) {
    // 假设at_chops提供了类似的数据过滤功能
    // 在这里我们手动实现过滤以模拟其功能
    return data.where(predicate).toList();
  }

  List<Map<String, dynamic>> _sortData(
      List<Map<String, dynamic>> data, int Function(Map<String, dynamic>, Map<String, dynamic>) compare) {
    // 假设at_chops提供了类似的数据排序功能
    // 在这里我们手动实现排序以模拟其功能
    return data..sort(compare);
  }

  // 如果at_chops提供了聚合功能,你可以在这里添加类似的方法
  // 例如:_aggregateData(...)
}

注意事项

  1. 实际API:上述代码中的_filterData_sortData方法是为了模拟at_chops可能提供的功能。你需要查阅at_chops的实际文档来了解其提供的API,并相应地替换这些手动实现的方法。

  2. 错误处理:在实际应用中,添加适当的错误处理逻辑来处理可能的异常情况,例如数据格式不正确或插件功能调用失败。

  3. 性能考虑:对于大型数据集,考虑使用更高效的数据处理算法或分批处理数据以避免性能瓶颈。

请确保查阅at_chops的官方文档以获取准确的API信息和最佳实践。如果at_chops不存在或具有不同的功能集,请考虑使用其他流行的数据处理和分析插件或库。

回到顶部