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

能否用Django生成的私钥在Flutter端解密密码?及报错解决

问题解决方案:Flutter端使用Django生成的RSA私钥解密数据

核心问题分析

报错的根源有两个关键不匹配:

  1. 加密/解密填充算法不一致:后端使用OAEP填充(搭配SHA256和MGF1-SHA256),但Flutter端用的是PKCS1Encoding(PKCS#1 v1.5填充),两者无法兼容。
  2. 加密数据编码方式错误:后端返回的是原始加密字节,Flutter直接用Base64解析非Base64格式的字节,必然抛出FormatException。

此外需确保PKCS8格式的私钥能被Flutter正确解析。


分步解决方案

1. 修改后端加密函数,返回Base64编码的加密结果

后端加密后的原始字节无法直接在HTTP传输或被Base64解析,需转为Base64字符串:

import base64
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.backends import default_backend

def encrypt(data, key):
    key = serialization.load_pem_public_key(
        key.encode(),
        backend=default_backend()
    )

    data = key.encrypt(
        data.encode(),
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    # 将加密字节转为Base64字符串返回
    return base64.b64encode(data).decode('utf-8')

2. 调整Flutter解密函数,匹配OAEP填充算法

替换PKCS1编码为OAEP编码,保持哈希算法与后端一致:

import 'dart:convert';
import 'package:pointycastle/pointycastle.dart';
import 'package:shared_preferences/shared_preferences.dart';

dynamic decryptByPrivateKey(String content) async {
  final prefs = await SharedPreferences.getInstance();
  final private = prefs.getString('privateKey')!;

  // 解析PKCS8格式的PEM私钥
  RSAKeyParser parser = RSAKeyParser();
  RSAPrivateKey privateKey = parser.parse(private) as RSAPrivateKey;

  // 使用与后端一致的OAEP填充配置
  AsymmetricBlockCipher cipher = OAEPEncoding(
    RSAEngine(),
    SHA256Digest(),
    SHA256Digest(),
    null, // 与后端label保持一致为null
  );
  
  cipher.init(false, PrivateKeyParameter<RSAPrivateKey>(privateKey));
  
  // 先解码Base64,再执行解密
  Uint8List encryptedBytes = base64Decode(content);
  Uint8List decryptedBytes = cipher.process(encryptedBytes);
  
  return utf8.decode(decryptedBytes);
}

3. 额外验证项

  • 检查SharedPreferences中保存的私钥是否完整:确保包含-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----标记,且无换行符丢失或字符截断。
  • 若私钥解析仍失败,可替换解析方式(依赖basic_utils库):
    import 'package:basic_utils/basic_utils.dart';
    
    // 替换解析代码
    RSAPrivateKey privateKey = CryptoUtils.rsaPrivateKeyFromPem(private);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:56:07