You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter PointyCastle生成RSA密钥传入Java解析报InvalidKeyException错误

问题根因排查
  • 密钥格式不匹配:Flutter侧PointyCastle默认导出的是PKCS1格式的RSA公钥,而Java原生X509EncodedKeySpec仅支持带X.509头的公钥格式,缺少算法标识头的PKCS1公钥无法被Java解析,直接触发你遇到的Error parsing public key报错。
  • 传参逻辑错误:Flutter侧加密按钮的传参使用了共享变量futureText,该变量会被点击其他按钮(比如获取私钥、签名)的结果覆盖,可能出现公钥传成私钥、私钥传成公钥的问题。
  • Java侧逻辑漏洞:MainActivity的方法处理逻辑没有分支返回,不管加密/解密是否执行成功,最后都会走到result.notImplemented(),导致Flutter侧收到未实现的错误。
解决方案

步骤1:修改Flutter侧密钥导出格式

将公钥导出格式从PKCS1改为X.509格式,私钥导出格式从PKCS1改为PKCS8格式,适配Java的密钥解析规则,示例工具方法如下:

import 'dart:convert';
import 'package:pointycastle/asn1.dart';
import 'package:pointycastle/api.dart' as crypto;
import 'package:pointycastle/rsa.dart';

// 导出X.509格式公钥,适配Java X509EncodedKeySpec
String encodePublicKeyToX509Pem(RSAPublicKey publicKey) {
  // 构造算法标识序列
  final algorithmSeq = ASN1Sequence();
  algorithmSeq.add(ASN1ObjectIdentifier.fromName('rsaEncryption'));
  algorithmSeq.add(ASN1Null());

  // 构造RSA公钥参数序列
  final pubKeySeq = ASN1Sequence();
  pubKeySeq.add(ASN1Integer(publicKey.modulus));
  pubKeySeq.add(ASN1Integer(publicKey.exponent));
  final pubKeyBitStr = ASN1BitString(pubKeySeq.encode());

  // 构造顶级序列
  final topSeq = ASN1Sequence();
  topSeq.add(algorithmSeq);
  topSeq.add(pubKeyBitStr);

  final pubKeyBase64 = base64.encode(topSeq.encode());
  return '-----BEGIN PUBLIC KEY-----\n$pubKeyBase64\n-----END PUBLIC KEY-----';
}

// 导出PKCS8格式私钥,适配Java PKCS8EncodedKeySpec
String encodePrivateKeyToPKCS8Pem(RSAPrivateKey privateKey) {
  final version = ASN1Integer(BigInt.from(0));

  final algorithmSeq = ASN1Sequence();
  algorithmSeq.add(ASN1ObjectIdentifier.fromName('rsaEncryption'));
  algorithmSeq.add(ASN1Null());

  final privateKeySeq = ASN1Sequence();
  privateKeySeq.add(ASN1Integer(BigInt.from(0)));
  privateKeySeq.add(ASN1Integer(privateKey.modulus));
  privateKeySeq.add(ASN1Integer(privateKey.publicExponent));
  privateKeySeq.add(ASN1Integer(privateKey.privateExponent));
  privateKeySeq.add(ASN1Integer(privateKey.p));
  privateKeySeq.add(ASN1Integer(privateKey.q));
  privateKeySeq.add(ASN1Integer(privateKey.privateExponent.remainder(privateKey.p - BigInt.one)));
  privateKeySeq.add(ASN1Integer(privateKey.privateExponent.remainder(privateKey.q - BigInt.one)));
  privateKeySeq.add(ASN1Integer(privateKey.q!.modInverse(privateKey.p!)));

  final privateKeyOctet = ASN1OctetString(privateKeySeq.encode());

  final topSeq = ASN1Sequence();
  topSeq.add(version);
  topSeq.add(algorithmSeq);
  topSeq.add(privateKeyOctet);

  final privKeyBase64 = base64.encode(topSeq.encode());
  return '-----BEGIN PRIVATE KEY-----\n$privKeyBase64\n-----END PRIVATE KEY-----';
}

步骤2:修复Flutter侧传参逻辑

直接从已生成的keyPair中获取公私钥,不要复用被覆盖的futureText变量:

MaterialButton(
  color: Colors.red,
  child: Text("Encrypt"),
  onPressed: () async {
    // 直接从keyPair生成符合Java要求的密钥
    final pubPem = encodePublicKeyToX509Pem(keyPair.publicKey as RSAPublicKey);
    final privPem = encodePrivateKeyToPKCS8Pem(keyPair.privateKey as RSAPrivateKey);
    futureText = methodC("encryptMsg",
        priv: RSA().removePemHeaderAndFooter(privPem),
        pub: RSA().removePemHeaderAndFooter(pubPem),
        msg: _controller.text);
    setState(() {});
  },
),

步骤3:修复Java侧逻辑漏洞

在每个方法分支处理完成后添加return,避免执行到result.notImplemented():

if(call.method.equals("encryptMsg")) {
    try {
        String encryptedString = Base64.getEncoder().encodeToString(rsa.encrypt(msg, pubKey));
        result.success(encryptedString);
    } catch (Exception e) {
        result.error("ENCRYPT_ERROR", e.getMessage(), null);
    }
    return; // 新增返回,避免走到后续逻辑
}
else if(call.method.equals("decryptMsg")) {
    try {
        byte[] encryptedBytes = Base64.getDecoder().decode(msg);
        String decryptedString = rsa.decrypt(encryptedBytes, privKey);
        result.success(decryptedString);
    } catch (Exception e) {
        result.error("DECRYPT_ERROR", e.getMessage(), null);
    }
    return; // 新增返回
}
result.notImplemented();

内容的提问来源于stack exchange,提问作者Brightcode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 06:15:08