flutter如何实现rsa分段加密
在Flutter中如何实现RSA的分段加密?目前使用encrypt包处理较长的数据时遇到报错,不清楚该如何正确分段处理。求具体实现代码或思路,尤其针对超过密钥长度的数据该如何拆分加密?
2 回复
在Flutter中实现RSA分段加密,可使用encrypt库。步骤如下:
- 加载公钥,生成RSA加密器。
- 计算分段大小(如密钥长度/8 - 11)。
- 将数据按分段大小拆分,逐段加密。
- 合并加密结果,输出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');
}
关键说明
-
分段大小计算:2048位RSA密钥最大加密数据长度为
256 - 42 = 214字节(使用OAEP填充) -
填充方式:使用OAEP填充,比PKCS#1更安全
-
性能优化:对于长文本,分段加密避免内存溢出
-
错误处理:实际应用中应添加try-catch处理加密异常
这种实现方式适用于加密超过RSA密钥限制的长文本数据。

