You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter中解密Base64编码的RSA加密字符串遇问题求助

解决Flutter encrypt包解密OpenSSL RSA加密内容失败的问题

看起来你遇到的问题核心是加密和解密时的填充模式不匹配,加上对加密后二进制数据的错误处理,导致了解密失败。下面一步步帮你解决:

问题根源分析

首先看你用的OpenSSL命令:

echo "thesearesecretlogininfos"|openssl rsautl -encrypt -pubin -inkey public.pem |openssl base64

openssl rsautl -encrypt默认使用的是PKCS#1 v1.5填充,但Flutter的encrypt包中,RSA实现默认采用的是OAEP填充——两种填充规则不兼容,这就是你拿到Unsupported block type错误的直接原因。

另外,你尝试把Base64解码后的二进制数据直接转UTF8,这本身就不合理:RSA加密后的结果是随机二进制流,不是合法的UTF8编码,所以必然会抛出FormatException

修正后的解密代码

只需要在创建Encrypter时显式指定PKCS#1 v1.5填充即可,同时解密不需要公钥,只需要私钥就够了:

import 'package:encrypt/encrypt.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:pointycastle/asymmetric/api.dart';

String base64encryptedLoginID;
String newloginID;

void decrypt(BuildContext context) async {
  try {
    // 加载私钥文件
    final myPrivateKey = await rootBundle.loadString('assets/private.pem');
    final privateKey = RSAKeyParser().parse(myPrivateKey) as RSAPrivateKey;

    // 创建加密器并指定PKCS#1 v1.5填充
    final encrypter = Encrypter(RSA(
      privateKey: privateKey,
      encoding: RSAEncoding.PKCS1, // 关键:指定和OpenSSL一致的填充模式
    ));

    // 解密Base64编码的密文
    newloginID = encrypter.decrypt(Encrypted.fromBase64(base64encryptedLoginID));
    print('解密成功:$newloginID');
    // 这里可以添加后续的业务逻辑处理
  } catch (e) {
    print('解密失败:$e');
    // 处理解密错误,比如提示用户密文无效或密钥错误
  }
}

额外的注意事项

  1. 加密时的换行符问题
    你用echo命令时,默认会在明文末尾添加一个换行符,导致加密的内容包含这个换行。如果不需要的话,记得加上-n参数:

    echo -n "thesearesecretlogininfos"|openssl rsautl -encrypt -pubin -inkey public.pem |openssl base64
    

    这样加密的就是纯明文内容,解密后不会多出换行。

  2. 验证密文和密钥的有效性
    可以先在本地用OpenSSL验证解密是否正常,排除密文或密钥本身的问题:

    echo "你的Base64密文内容" | base64 -d | openssl rsautl -decrypt -inkey private.pem
    

    如果这条命令能输出正确的明文,说明密文和密钥没问题,问题就确实出在Flutter代码的填充模式上。

内容的提问来源于stack exchange,提问作者Medien-Treibhaus

火山引擎 最新活动