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

解密遇FormatException无效字符错误,求RSA加解密代码排查

解密RSA加密字符串时出现FormatException的问题解决

错误信息

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: FormatException: Invalid character (at character 1)

原始代码

加密代码

/// Encrypting String
String encrypt(String plaintext, RSAPublicKey publicKey) {
  var cipher = new RSAEngine()
    ..init(true, new PublicKeyParameter<RSAPublicKey>(publicKey));

  var utf8Encoded = utf8.encode(plaintext);

  var encoded64 = base64.encode(utf8Encoded);

  var cipherText = cipher.process(new Uint8List.fromList(encoded64.codeUnits));

  var result = String.fromCharCodes(cipherText);

  return result;
}

解密代码

/// Decrypting String
String decrypt(String ciphertext, RSAPrivateKey privateKey) {
  var cipher = new RSAEngine()
    ..init(false, new PrivateKeyParameter<RSAPrivateKey>(privateKey));

  var decrypted = cipher.process(new Uint8List.fromList(ciphertext.codeUnits));

  var encoded64 = String.fromCharCodes(decrypted);

  var decoded64 = utf8.decode(base64.decode(encoded64));

  return decoded64;
}

问题原因

  1. RSA加密输出的是二进制字节流,直接用String.fromCharCodes将其转换为字符串会引入大量非UTF-8兼容的无效字符,这些字符在存储或传输过程中可能被损坏,导致解密时无法还原出合法的Base64数据。
  2. 加密流程中多余的Base64编码步骤完全没必要,反而增加了字符转换出错的概率。

解决办法

调整加密和解密流程,直接对原始字节进行RSA操作,用Base64处理加密后的二进制数据,避免无效字符问题。

修正后的加密代码

/// Encrypting String
String encrypt(String plaintext, RSAPublicKey publicKey) {
  var cipher = RSAEngine()
    ..init(true, PublicKeyParameter<RSAPublicKey>(publicKey));

  // 直接加密原始UTF-8字节
  var utf8Encoded = utf8.encode(plaintext);
  var cipherText = cipher.process(Uint8List.fromList(utf8Encoded));
  
  // 将加密后的二进制字节转为Base64字符串,确保安全传输/存储
  return base64.encode(cipherText);
}

修正后的解密代码

/// Decrypting String
String decrypt(String ciphertext, RSAPrivateKey privateKey) {
  var cipher = RSAEngine()
    ..init(false, PrivateKeyParameter<RSAPrivateKey>(privateKey));

  // 先把Base64字符串解码为加密字节
  var cipherBytes = base64.decode(ciphertext);
  var decryptedBytes = cipher.process(cipherBytes);
  
  // 直接将解密后的字节转为原始字符串
  return utf8.decode(decryptedBytes);
}

修正说明

  • 加密时跳过冗余的Base64编码,直接对原始UTF-8字节加密,再将加密结果转为Base64字符串,避免二进制转字符串的编码问题。
  • 解密时先还原加密字节,解密后直接用UTF-8解码得到原始字符串,彻底消除无效字符导致的FormatException。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:01:45