Flutter加密解密插件xkyber_crypto的使用

Flutter加密解密插件xkyber_crypto的使用

XKyber_crypto

XKyber_crypto 是一个用于后量子加密的Dart库,它基于Kyber算法提供了一个密钥封装机制(KEM)。Kyber是一种由NIST选定用于标准化的后量子密码学方案,旨在抵御来自量子计算机的攻击。

特性

  • 使用Kyber KEM生成公钥和私钥对。
  • 使用公钥封装共享密钥。
  • 使用私钥解封共享密钥。
  • 共享密钥可用于与对称加密算法(如AES-GCM)结合来加密或解密任意消息。
  • 使用SHAKE128,并完全遵循官方Kyber规范。

前提条件

在使用该库之前,请确保你已安装以下内容:

  • Dart SDK: 版本2.12.0或更高版本。
  • Flutter(可选,如果你正在使用Flutter项目)。
  • 一个编辑器,如Visual Studio Code或IntelliJ,以方便开发。

安装

要安装此库,请将其依赖项添加到你的 pubspec.yaml 文件中:

dependencies:
  xkyber_crypto:
    git:
      url: https://github.com/xscriptorcode/xkyber_crypto.git

然后更新依赖项:

dart pub get

使用示例

这是一个基本的使用示例:

// example/general_example.dart
// ignore_for_file: avoid_print, always_specify_types

import 'dart:typed_data';
import 'package:xkyber_crypto/xkyber_crypto.dart';

Future<void> main() async {
  print("=== XKyber_crypto Usage Example ===");

  // 1. 密钥对生成
  // 生成一个Kyber密钥对。
  KyberKeyPair keypair = KyberKeyPair.generate();
  print("公钥 (${keypair.publicKey.length} 字节):");
  print(keypair.publicKey);
  print("私钥 (${keypair.secretKey.length} 字节):");
  print(keypair.secretKey);

  // 2. 封装
  // 使用公钥封装一个共享密钥。
  KyberEncapsulationResult encapsulationResult = KyberKEM.encapsulate(keypair.publicKey);
  Uint8List ciphertext = encapsulationResult.ciphertextKEM;
  Uint8List sharedSecretEnc = encapsulationResult.sharedSecret;
  print("\n密文 (${ciphertext.length} 字节):");
  print(ciphertext);
  print("\n封装后的共享密钥 (${sharedSecretEnc.length} 字节):");
  print(sharedSecretEnc);

  // 3. 解封
  // 使用私钥解封以恢复共享密钥。
  Uint8List sharedSecretDec = KyberKEM.decapsulate(ciphertext, keypair.secretKey);
  print("\n解封后的共享密钥 (${sharedSecretDec.length} 字节):");
  print(sharedSecretDec);

  // 4. 验证两个共享密钥是否匹配。
  if (sharedSecretEnc.toString() == sharedSecretDec.toString()) {
    print("\n共享密钥匹配!");
  } else {
    print("\n共享密钥不匹配!");
  }

  // 5. (可选)使用共享密钥进行对称加密
  // 这里我们演示如何生成对称密钥,加密消息,然后使用AES-GCM实现解密。
  Uint8List symKey = await XKyberCrypto.generateSymmetricKey();
  String plaintext = "这是一条秘密消息。";
  String encrypted = await XKyberCrypto.symmetricEncrypt(plaintext, symKey);
  String decrypted = await XKyberCrypto.symmetricDecrypt(encrypted, symKey);

  print("\n对称加密示例:");
  print("明文: $plaintext");
  print("加密(Base64): $encrypted");
  print("解密: $decrypted");
}

测试库

你可以通过以下测试文件来验证库的功能:

// /example/main.dart == example file
// ignore_for_file: avoid_print, always_specify_types

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

import 'package:test/test.dart';
import 'package:xkyber_crypto/xkyber_crypto.dart'; // Adjust the path as necessary

void main() {
  group('随机字节', () {
    test('randombytes返回正确的字节数', () {
      final bytes = randombytes(16);
      expect(bytes.length, equals(16));
    });
  });

  group('SHAKE128', () {
    test('生成请求长度的输出', () {
      final seed = Uint8List.fromList(List.generate(10, (i) => i));
      final out = shake128(seed, 64);
      expect(out.length, equals(64));
    });
  });

  group('多项式运算', () {
    test('多项式的序列化/反序列化', () {
      final poly = Poly();
      // 初始化多项式系数为测试值。
      for (int i = 0; i < KYBER_N; i++) {
        poly.coeffs[i] = i % KYBER_Q;
      }
      final bytes = polytobytes(poly);
      final poly2 = polyfrombytes(bytes);
      for (int i = 0; i < KYBER_N; i++) {
        expect(poly2.coeffs[i] % KYBER_Q, equals(poly.coeffs[i] % KYBER_Q),
            reason: '系数 $i 不匹配');
      }
    });

    test('多项式的压缩/解压缩', () {
      final poly = Poly();
      // 使用测试多项式;这里我们使用(i * 7) % KYBER_Q。
      for (int i = 0; i < KYBER_N; i++) {
        poly.coeffs[i] = (i * 7) % KYBER_Q;
      }
      final compressed = polycompress(poly);
      final decompressed = polydecompress(compressed);
      for (int i = 0; i < KYBER_N; i++) {
        final diff = (poly.coeffs[i] - decompressed.coeffs[i]).abs();
        // 由于3位压缩引起的量化误差,增加容差至209。
        expect(diff, lessThan(209),
            reason: '系数 $i: 差异 $diff 超过容差');
      }
    });
  });

  group('多项式向量运算', () {
    test('多项式向量的序列化/反序列化', () {
      final polyVec = PolyVec();
      // 用测试值设置每个多项式。
      for (int i = 0; i < KYBER_K; i++) {
        for (int j = 0; j < KYBER_N; j++) {
          polyVec.vec[i].coeffs[j] = (i * 123 + j) % KYBER_Q;
        }
      }
      final bytes = polyvectobytes(polyVec);
      final polyVec2 = polyvecfrombytes(bytes);
      for (int i = 0; i < KYBER_K; i++) {
        for (int j = 0; j < KYBER_N; j++) {
          expect(polyVec2.vec[i].coeffs[j] % KYBER_Q,
              equals(polyVec.vec[i].coeffs[j] % KYBER_Q),
              reason: '多项式向量[$i] 系数 $j 不匹配');
        }
      }
    });
  });

  group('IND-CPA 和 KEM', () {
    test('密钥对生成、封装和解封', () {
      // 生成密钥对。
      final keypair = KyberKeyPair.generate();
      expect(keypair.publicKey.length, equals(KYBER_PUBLICKEYBYTES));
      expect(keypair.secretKey.length, equals(KYBER_SECRETKEYBYTES));

      // 使用公钥封装。
      final encapsulationResult = KyberKEM.encapsulate(keypair.publicKey);
      final ciphertext = encapsulationResult.ciphertextKEM;
      final sharedSecretEnc = encapsulationResult.sharedSecret;

      // 使用私钥解封。
      final sharedSecretDec = KyberKEM.decapsulate(ciphertext, keypair.secretKey);

      // 共享密钥应该匹配。
      expect(sharedSecretDec, equals(sharedSecretEnc));
    });
  });

  group('对称加密(AES-GCM)', () {
    test('对称加密和解密', () async {
      final key = await XKyberCrypto.generateSymmetricKey();
      final plaintext = "测试消息用于对称加密。";
      final encrypted = await XKyberCrypto.symmetricEncrypt(plaintext, key);
      final decrypted = await XKyberCrypto.symmetricDecrypt(encrypted, key);
      expect(decrypted, equals(plaintext));
    });
  });

  group('常量时间比较', () {
    test('constantTimeCompare正确工作', () {
      final a = Uint8List.fromList([1, 2, 3, 4, 5]);
      final b = Uint8List.fromList([1, 2, 3, 4, 5]);
      final c = Uint8List.fromList([1, 2, 3, 4, 6]);
      expect(constantTimeCompare(a, b), isTrue);
      expect(constantTimeCompare(a, c), isFalse);
    });
  });
}

示例说明

此示例演示了以下内容:

  • 生成一个Kyber密钥对。
  • 使用公钥(pk)封装共享密钥。
  • 使用私钥(sk)解封共享密钥。
  • 使用共享密钥(ss)进行对称加密。

API

主函数

  • cryptoKemKeypair(Uint8List pk, Uint8List sk):生成一个Kyber密钥对。
  • cryptoKemEnc(Uint8List c, Uint8List ss, Uint8List pk):使用公钥(pk)封装共享密钥(ss),并生成密文(c)。
  • cryptoKemDec(Uint8List ss, Uint8List c, Uint8List sk):使用私钥(sk)解封密文(c)以恢复共享密钥(ss)。

  • KyberKeyPair
    • generate():生成一个Kyber密钥对(公钥、私钥)。
    • publicKey, privateKey:表示密钥的字节数组。

项目结构

  • <strong><code>lib/</code></strong>
    • 包含库的主要实现。
  • kem.dart:核心Kyber KEM函数(cryptoKemEnc, cryptoKemDec, cryptoKemKeypair)。
  • kyber_keypair.dart:处理密钥生成和实用程序。
  • poly.dart, polyvec.dart, ntt.dart, params.dart等:核心Kyber实现(NTT、多项式操作、参数定义)。
  • shake.dart:SHAKE128实现。
  • reduce.dart, fq.dart:模算术和域操作。
  • <strong><code>example/</code></strong>
    • 示例代码,帮助理解库的使用。
  • <strong><code>test/</code></strong>
    • 自动化测试,验证库的功能。

依赖项

该库使用以下依赖项:

  • <strong><code>crypto: ^3.0.6</code></strong>:提供常见的加密功能。
  • <strong><code>pointycastle: ^3.9.1</code></strong>:Dart中的高级加密库。
  • <strong><code>lints: ^5.0.0</code></strong>:建立Dart代码的风格规则和最佳实践。

确保使用最新版本以保证兼容性和性能。


测试和质量

自动化测试

  • 关键生成和共享密钥:确保生成的密钥和共享密钥的正确性。
  • 封装/解封:验证cryptoKemEnccryptoKemDec生成匹配的共享密钥。
  • 数学运算:检查NTT、模算术和噪声分布。

运行测试:

dart test

更多关于Flutter加密解密插件xkyber_crypto的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter加密解密插件xkyber_crypto的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用xkyber_crypto插件进行加密和解密的示例代码。这个插件通常用于处理加密操作,比如对称加密、非对称加密等。不过请注意,xkyber_crypto是一个假设的插件名称,实际使用时你需要确保插件名称正确且已在pub.dev上可用,或已作为私有包引入你的项目中。

首先,你需要在pubspec.yaml文件中添加该插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  xkyber_crypto: ^x.y.z  # 替换为实际的版本号

然后运行flutter pub get来安装依赖。

接下来,是一个简单的Flutter应用示例,展示了如何使用xkyber_crypto进行加密和解密操作。

import 'package:flutter/material.dart';
import 'package:xkyber_crypto/xkyber_crypto.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('xkyber_crypto 示例'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              TextField(
                decoration: InputDecoration(labelText: '原文'),
                controller: _originalTextController,
                maxLines: 4,
              ),
              SizedBox(height: 16),
              ElevatedButton(
                onPressed: _encryptText,
                child: Text('加密'),
              ),
              SizedBox(height: 16),
              TextField(
                decoration: InputDecoration(labelText: '加密后文本'),
                controller: _encryptedTextController,
                maxLines: 4,
                readOnly: true,
              ),
              SizedBox(height: 16),
              ElevatedButton(
                onPressed: _decryptText,
                child: Text('解密'),
              ),
              SizedBox(height: 16),
              TextField(
                decoration: InputDecoration(labelText: '解密后文本'),
                controller: _decryptedTextController,
                maxLines: 4,
                readOnly: true,
              ),
            ],
          ),
        ),
      ),
    );
  }

  final _originalTextController = TextEditingController();
  final _encryptedTextController = TextEditingController();
  final _decryptedTextController = TextEditingController();

  void _encryptText() async {
    final originalText = _originalTextController.text;
    if (originalText.isEmpty) {
      return;
    }

    try {
      // 假设使用AES加密,密钥和IV需要预先定义或安全生成
      final key = Uint8List.fromList(List.generate(32, (i) => i % 256));
      final iv = Uint8List.fromList(List.generate(16, (i) => i % 256));

      // 使用AES加密
      final encryptedBytes = await XkyberCrypto.aesEncrypt(
        originalText.codeUnits,
        key,
        iv,
      );

      // 转换为Base64字符串显示
      _encryptedTextController.text = base64Encode(encryptedBytes);
    } catch (e) {
      print('加密失败: $e');
    }
  }

  void _decryptText() async {
    final encryptedText = _encryptedTextController.text;
    if (encryptedText.isEmpty) {
      return;
    }

    try {
      // 假设使用AES解密,密钥和IV与加密时相同
      final key = Uint8List.fromList(List.generate(32, (i) => i % 256));
      final iv = Uint8List.fromList(List.generate(16, (i) => i % 256));

      // 将Base64字符串转换回字节数组
      final encryptedBytes = base64Decode(encryptedText);

      // 使用AES解密
      final decryptedBytes = await XkyberCrypto.aesDecrypt(
        encryptedBytes,
        key,
        iv,
      );

      // 转换为字符串显示
      _decryptedTextController.text = String.fromCharCodes(decryptedBytes);
    } catch (e) {
      print('解密失败: $e');
    }
  }
}

注意事项

  1. 插件的API可能有所不同,你需要查阅xkyber_crypto的实际文档来确认加密和解密函数的具体使用方法和参数。
  2. 密钥(key)和初始化向量(IV)应该安全地生成和存储,不应硬编码在代码中。
  3. 加密操作通常是异步的,所以这里使用了asyncawait
  4. 加密后的数据通常会被转换为Base64字符串以便于显示和传输,这里使用了base64Encodebase64Decode函数(这些函数可能需要从dart:convert导入)。

这个示例仅用于演示目的,实际项目中应根据具体需求和安全要求进行调整。

回到顶部