Flutter RSA加密解密实现

我在Flutter项目中需要使用RSA进行加密解密,但在实现过程中遇到了一些问题。具体表现为:

  1. 如何正确生成RSA的公钥和私钥?我尝试使用pointycastle库,但对密钥对的生成流程不太清楚。

  2. 加密后的数据在解密时出现错误,可能是密钥格式或填充方式的问题,但不确定具体原因。是否有标准的密钥格式要求?

  3. 不同平台(Android/iOS)的RSA加密结果是否一致?是否需要针对不同平台做特殊处理?

希望能得到具体的代码示例或实现思路,最好包含密钥生成、加密、解密的完整流程说明。谢谢!

3 回复

作为一个屌丝程序员,我来分享下Flutter中RSA加密解密的实现。首先,你需要使用pointycastleencrypt这两个包。

  1. 生成公私钥:用pointycastle生成RSA密钥对。
import 'package:pointycastle/api.dart';
import 'package:pointycastle/key_generators/api.dart';

AsymmetricKeyPair<PublicKey, PrivateKey> generateKeys() {
  final keyGenerator = KeyGenerator('RSA')..init(ParametersWithRandom(RSAKeyGeneratorParameter(2048, 65537), SecureRandomImpl("AES/CTR/PRNG")));
  return keyGenerator.generateKeyPair();
}
  1. 加密:用公钥加密数据。
import 'package:encrypt/encrypt.dart' as encrypt;

String encryptData(String plainText, PublicKey publicKey) {
  var encrypter = encrypt.Encrypter(encrypt.RSA(publicKey: publicKey));
  var encrypted = encrypter.encrypt(plainText);
  return encrypted.base64;
}
  1. 解密:用私钥解密数据。
String decryptData(String encryptedBase64, PrivateKey privateKey) {
  var encrypter = encrypt.Encrypter(encrypt.RSA(privateKey: privateKey));
  var encrypted = encrypt.Encrypted.fromBase64(encryptedBase64);
  var decrypted = encrypter.decrypt(encrypted);
  return decrypted;
}

记住,RSA适合小数据加密,大文件传输建议结合对称加密。

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


作为一个屌丝程序员,我会告诉你如何用Flutter实现RSA加密和解密。首先,你需要添加pointycastleflutter_secure_storage依赖到你的pubspec.yaml中。然后你可以这样实现:

  1. 生成RSA密钥对:
import 'package:pointycastle/export.dart';

void generateKeys() {
  var secureRandom = FortunaRandom();
  var seeds = <int>[];
  var random = Random.secure();
  for (var i = 0; i < 32; i++) {
    seeds.add(random.nextInt(256));
  }
  secureRandom.seed(KeyParameter(Uint8List.fromList(seeds)));

  var rngParams = ParametersWithRandom(RSAKeyGeneratorParameters(BigInt.parse("65537"), 2048, 96), secureRandom);
  var keyGenerator = RSAKeyGenerator()..init(rngParams);

  AsymmetricKeyPair<RSAPublicKey, RSAPrivateKey> pair = keyGenerator.generateKeyPair();
}
  1. 加密数据:
Uint8List encryptData(String data, RSAPublicKey publicKey) {
  var transformer = OAEPEncoding(RSAEngine());
  transformer.init(true, PublicKeyParameter<RSAPublicKey>(publicKey));
  return transformer.process(Uint8List.fromList(data.codeUnits));
}
  1. 解密数据:
String decryptData(Uint8List encryptedData, RSAPrivateKey privateKey) {
  var transformer = OAEPEncoding(RSAEngine());
  transformer.init(false, PrivateKeyParameter<RSAPrivateKey>(privateKey));
  return String.fromCharCodes(transformer.process(encryptedData));
}

记得处理异常和错误,保护好私钥。这只是一个简单的示例,实际应用中需要更多的安全措施。

Flutter RSA加密解密实现

在Flutter中实现RSA加密解密,可以使用pointycastleasn1lib这两个库。

安装依赖

首先在pubspec.yaml中添加依赖:

dependencies:
  pointycastle: ^3.1.1
  asn1lib: ^1.0.0

然后运行flutter pub get

RSA加密解密实现代码

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

import 'package:pointycastle/asymmetric/api.dart';
import 'package:pointycastle/asymmetric/rsa.dart';
import 'package:pointycastle/key_generators/api.dart';
import 'package:pointycastle/pointycastle.dart';
import 'package:asn1lib/asn1lib.dart';

class RSAHelper {
  // 生成RSA密钥对
  static AsymmetricKeyPair<PublicKey, PrivateKey> generateKeyPair() {
    final keyGen = KeyGenerator('RSA');
    final params = RSAKeyGeneratorParameters(BigInt.from(65537), 2048, 12);
    keyGen.init(ParametersWithRandom(params, Random.secure()));
    return keyGen.generateKeyPair();
  }

  // 公钥加密
  static String encrypt(String plainText, RSAPublicKey publicKey) {
    final cipher = RSAEngine()
      ..init(true, PublicKeyParameter<RSAPublicKey>(publicKey));
    
    final textBytes = Uint8List.fromList(utf8.encode(plainText));
    final encrypted = cipher.process(textBytes);
    
    return base64.encode(encrypted);
  }

  // 私钥解密
  static String decrypt(String encrypted, RSAPrivateKey privateKey) {
    final cipher = RSAEngine()
      ..init(false, PrivateKeyParameter<RSAPrivateKey>(privateKey));
    
    final encryptedBytes = base64.decode(encrypted);
    final decrypted = cipher.process(encryptedBytes);
    
    return utf8.decode(decrypted);
  }

  // 从PEM格式字符串解析公钥
  static RSAPublicKey parsePublicKeyFromPem(String pem) {
    final pemString = pem
        .replaceAll('-----BEGIN PUBLIC KEY-----', '')
        .replaceAll('-----END PUBLIC KEY-----', '')
        .replaceAll('\n', '');
    
    final bytes = base64.decode(pemString);
    final asn1Object = ASN1Sequence.fromBytes(bytes);
    final bitString = asn1Object.elements[1] as ASN1BitString;
    final publicKeyASN1 = ASN1Sequence.fromBytes(bitString.contentBytes());
    
    final modulus = publicKeyASN1.elements[0] as ASN1Integer;
    final exponent = publicKeyASN1.elements[1] as ASN1Integer;
    
    return RSAPublicKey(modulus.valueAsBigInteger, exponent.valueAsBigInteger);
  }

  // 从PEM格式字符串解析私钥
  static RSAPrivateKey parsePrivateKeyFromPem(String pem) {
    final pemString = pem
        .replaceAll('-----BEGIN PRIVATE KEY-----', '')
        .replaceAll('-----END PRIVATE KEY-----', '')
        .replaceAll('\n', '');
    
    final bytes = base64.decode(pemString);
    final asn1Object = ASN1Sequence.fromBytes(bytes);
    final privateKeyASN1 = asn1Object.elements[2] as ASN1OctetString;
    final privateKeySequence = ASN1Sequence.fromBytes(privateKeyASN1.contentBytes());
    
    final modulus = privateKeySequence.elements[1] as ASN1Integer;
    final privateExponent = privateKeySequence.elements[3] as ASN1Integer;
    
    return RSAPrivateKey(modulus.valueAsBigInteger, privateExponent.valueAsBigInteger);
  }
}

使用示例

void main() async {
  // 生成密钥对
  final keyPair = RSAHelper.generateKeyPair();
  final publicKey = keyPair.publicKey as RSAPublicKey;
  final privateKey = keyPair.privateKey as RSAPrivateKey;
  
  // 加密
  const plainText = 'Hello, RSA!';
  final encrypted = RSAHelper.encrypt(plainText, publicKey);
  print('加密结果: $encrypted');
  
  // 解密
  final decrypted = RSAHelper.decrypt(encrypted, privateKey);
  print('解密结果: $decrypted');
  
  // 使用PEM格式密钥
  const publicPem = '''-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHC...'''; // 示例公钥
  const privatePem = '''-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7...'''; // 示例私钥
  
  final parsedPublicKey = RSAHelper.parsePublicKeyFromPem(publicPem);
  final parsedPrivateKey = RSAHelper.parsePrivateKeyFromPem(privatePem);
}

注意:实际使用时需要替换PEM格式的密钥对。

回到顶部