flutter如何实现rsa分段加密

在Flutter中如何实现RSA的分段加密?目前使用encrypt包处理较长的数据时遇到报错,不清楚该如何正确分段处理。求具体实现代码或思路,尤其针对超过密钥长度的数据该如何拆分加密?

2 回复

在Flutter中实现RSA分段加密,可使用encrypt库。步骤如下:

  1. 加载公钥,生成RSA加密器。
  2. 计算分段大小(如密钥长度/8 - 11)。
  3. 将数据按分段大小拆分,逐段加密。
  4. 合并加密结果,输出Base64编码。

示例代码:

import 'package:encrypt/encrypt.dart';

String rsaSegmentEncrypt(String plainText, RSAPublicKey publicKey) {
  final encrypter = Encrypter(RSA(publicKey: publicKey));
  final blockSize = (publicKey.modulus?.bitLength ?? 2048) ~/ 8 - 11;
  final encryptedBlocks = <String>[];
  
  for (int i = 0; i < plainText.length; i += blockSize) {
    final block = plainText.substring(i, i + blockSize);
    encryptedBlocks.add(encrypter.encrypt(block).base64);
  }
  
  return encryptedBlocks.join();
}

更多关于flutter如何实现rsa分段加密的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现RSA分段加密,可以使用pointycastle库。以下是完整实现步骤:

1. 添加依赖

dependencies:
  pointycastle: ^3.6.2

2. RSA分段加密实现代码

import 'dart:convert';
import 'dart:typed_data';
import 'package:pointycastle/api.dart';
import 'package:pointycastle/asymmetric/api.dart';
import 'package:pointycastle/asymmetric/oaep.dart';
import 'package:pointycastle/asymmetric/rsa.dart';

class RSAEncryption {
  static const int RSA_KEY_LENGTH = 2048; // RSA密钥长度
  static const int SEGMENT_SIZE = 214; // 分段大小(2048位密钥对应214字节)

  // RSA分段加密
  static String encryptWithPublicKey(String plainText, RSAPublicKey publicKey) {
    final encryptor = OAEPEncoding(RSAEngine())
      ..init(true, PublicKeyParameter<RSAPublicKey>(publicKey));

    final plainBytes = utf8.encode(plainText);
    final encryptedSegments = <Uint8List>[];

    // 分段加密
    for (int i = 0; i < plainBytes.length; i += SEGMENT_SIZE) {
      final end = (i + SEGMENT_SIZE < plainBytes.length) 
          ? i + SEGMENT_SIZE 
          : plainBytes.length;
      final segment = plainBytes.sublist(i, end);
      
      final encryptedSegment = encryptor.process(Uint8List.fromList(segment));
      encryptedSegments.add(encryptedSegment);
    }

    // 合并加密结果并转为Base64
    final totalLength = encryptedSegments.fold(0, (sum, segment) => sum + segment.length);
    final result = Uint8List(totalLength);
    int offset = 0;
    
    for (final segment in encryptedSegments) {
      result.setRange(offset, offset + segment.length, segment);
      offset += segment.length;
    }

    return base64.encode(result);
  }

  // 从PEM格式字符串创建公钥
  static RSAPublicKey parsePublicKeyFromPem(String pem) {
    // 移除PEM格式的头部和尾部
    final lines = pem.split('\n');
    final keyBase64 = lines
        .where((line) => !line.startsWith('---'))
        .join()
        .trim();
    
    final keyBytes = base64.decode(keyBase64);
    final asn1Parser = ASN1Parser(keyBytes);
    final topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
    
    final modulus = (topLevelSeq.elements[0] as ASN1Integer).valueAsBigInteger;
    final exponent = (topLevelSeq.elements[1] as ASN1Integer).valueAsBigInteger;
    
    return RSAPublicKey(modulus, exponent);
  }
}

3. 使用示例

void main() {
  // 示例公钥(替换为你的实际公钥)
  const publicKeyPem = '''
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
''';

  final publicKey = RSAEncryption.parsePublicKeyFromPem(publicKeyPem);
  
  final plainText = '这是一段需要加密的长文本...';
  final encrypted = RSAEncryption.encryptWithPublicKey(plainText, publicKey);
  
  print('加密结果: $encrypted');
}

关键说明

  1. 分段大小计算:2048位RSA密钥最大加密数据长度为 256 - 42 = 214 字节(使用OAEP填充)

  2. 填充方式:使用OAEP填充,比PKCS#1更安全

  3. 性能优化:对于长文本,分段加密避免内存溢出

  4. 错误处理:实际应用中应添加try-catch处理加密异常

这种实现方式适用于加密超过RSA密钥限制的长文本数据。

回到顶部