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

Python加密RSA数据后Dart解密报OAEP解码错误的排查与解决

Dart与Python RSA跨语言加密解密错误排查与解决

我在Dart中生成RSA密钥对,将PEM编码的公钥通过Socket发送给Python;Python接收并加载该公钥,加密明文后将密文返回给Dart。但Dart使用匹配的私钥解密时出现以下错误:

[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): decoding error #0      OAEPEncoding._decodeBlock (package:pointycastle/asymmetric/oaep.dart:452:7)

1. Dart端生成RSA密钥并发送PEM公钥

String produceKey(RSAPublicKey my_pub) {
String public_pem = rsa_helper.CryptoUtils.encodeRSAPublicKeyToPem(my_pub);  
return "//encryptedKEY" + public_pem; // 基于Socket通信
}

2. Python端接收密钥并加密数据

public_key = serialization.load_pem_public_key(bytes(mykey,'utf8'), backend=default_backend())
message = "send 10 BTC to halit"

message = base64.b64encode(bytes(message,'utf8'))

encrypted_message = public_key.encrypt(
    message,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA1()),
        algorithm=hashes.SHA1(),
        label=None
    )
)
b = base64.b64encode(encrypted_message)
base64_str = b.decode('utf8')
# 发送密文至客户端

3. Dart端初始解密代码(出错版本)

String cipher_text = serverResponse.substring(9);// 截取Socket返回的密文(跳过前9位标识符)
Uint8List plain_text = rsaDecrypt(my_private,cipher_text);// 使用私钥解密密文
print(plain_text);

备注

Socket通信已验证正常,发送的PEM公钥与生成的一致。

Dart解密工具方法

Uint8List rsaDecrypt(RSAPrivateKey myPrivate, Uint8List cipherText) {
final decryptor = OAEPEncoding(RSAEngine())
..init(false, PrivateKeyParameter<RSAPrivateKey>(myPrivate)); // false表示解密

return _processInBlocks(decryptor, cipherText);
}
// pointycastle包提供的解密方法

测试用例

给定密钥对:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCPGT5j+2qdxrKp
trWW4hZcIwdacuduH16J7FO/0URzKoXdA5M5xVXwU/6HxREkKp+A+XUQN8HZCILP
mQzXkmWCLWNQP92o6WUeZQW6bcXYt11mS9JmDhDPXwuiq33vEMJFlXi1L1Wrq2nR
WVHKsJAuwswCfEjBfVdrJjut88JGXD/w5Et3t3A/zVX2eGAM1sn97kt57/PESObP
RVLB+avTVAEAu4Qb3/uMvRlmDVgE6eE6pm5La+ObyVrfDdP41ly7zNf3VqgtM0dM
OuurDmIGigXLvbrbIsx/TVxmwXvtreWhSyBISKMUMPB2NgcnvEXjXkt+PO00dGcN
8NI3erI9AgMBAAECggEAeHXWqJHfqVu30NgmuxItong2W3S4z2IG0nIn+iRuy8fz
Eh9NU2eENaBvdtl02Y4r4YWdfv6A53ObsqhzQBFT9CbDIK3yqZt37QM7tDluQEXz
kQao4hJbIkYvZEua4qGn+K2gBF4Jb08H8ByRlt/VMBf5Zuo60O7zpRZ1TLUTSOhi
7V0Teuu8djneHRtLzPgnfvGa1Ok6f4ObZGFgoZqTXK9HXxEc4+nICQoYc8BsMUlL
iPFnBzU4MlvF5xUT4bYWqQjsQBoHM7zVrpAtZ3xKeSSdbkEWivYkt36h+RQLm3SM
/1M5Ji92MjoFnLawh2XbZ+QD3W4owSvtd91n48lH/QKBgQDEbBI/7kfew6WO921D
jaEEIRwDxOn0kYZhoGozU8zUWUQBfCfDR5MNJWELvioCfTWcyAJ/+ysalSezYIHU
nuSGe8YrFTWI/xkGdUk1rfdSehbcnoPBwAM7wgW+twIdJpCAk6VbVMdh2hQNKDEN
0hAawk2PGr+2zm0qHuJhL0benwKBgQC6gKrbyv9XV6Th7blU0cnvY1fF3pdBKBFx
U8oABAXi+8db2nUUxZ/zbOUUKFYd0yX5SukXArek8xrzPjf52CReL845k6M76fDy
uSK4xQz900rueRaOANU4XxW+n+afti6CuoB5IINKRIne1S9ZEpmbtVWi0Y59+ANf
1GmXgictowKBgFcD7V3HCK3GDIz2TcBUeNVkeY2t6VsAMQEE2KdeY2pbFUZ3IwJe
reVv/rr+BoxNvbdz36+krGa9VvYfNcTkkyaEpLinT60eHY7/3GvcYql2DrSzwHjP
wF7zyCnB1zzkvbVIM0PvndhajPF7MagGvD2ugD96QR4R+shjIDSfhgzPAoGBAI5b
8o+NNzULYH9YP1RgQnzpXrFaBCinFhFkPNegOoIVYApcCWzOoRZls8KcO4fOibjt
lliLKXTOYG71ujKK6s++O/M1H693FgWgjcFuIEmLxDGd2jqQpjC+W9HDKn4UyRHe
nHxY9f51rKucHOUnznrNgs2imdrLun+mmuccYR1zAoGAHDkVep3Hy7cXVGwJzVeS
lvAHadFlQ4TcvJqVv+uNB8hRsH7BZqsyWfnepWuy7MychkuWGHpiIpzBFxeMFvi1
aKa1yjNARIHQLpXvZntVVM7pb2hWFKTNyOwKMJrp8o2h0DJKOar7jlLyNs3ZIDFM
n7w9iHpANOewTaT8svyFnxI=
-----END PRIVATE KEY-----

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjxk+Y/tqncayqba1luIW
XCMHWnLnbh9eiexTv9FEcyqF3QOTOcVV8FP+h8URJCqfgPl1EDfB2QiCz5kM15Jl
gi1jUD/dqOllHmUFum3F2LddZkvSZg4Qz18Loqt97xDCRZV4tS9Vq6tp0VlRyrCQ
LsLMAnxIwX1XayY7rfPCRlw/8ORLd7dwP81V9nhgDNbJ/e5Lee/zxEjmz0VSwfmr
01QBALuEG9/7jL0ZZg1YBOnhOqZuS2vjm8la3w3T+NZcu8zX91aoLTNHTDrrqw5i
BooFy7262yLMf01cZsF77a3loUsgSEijFDDwdjYHJ7xF415LfjztNHRnDfDSN3qy
PQIDAQAB
-----END PUBLIC KEY-----

plain_text = "Send To Halit 10BTC";

Python生成的密文:

jQO/VTb2lJut94GB5ABgV5gXsd2ee3x++EUz9FaMMEn8zxSisfUY7qiaAtwfV8bIOw+rcvfmyfIdxngSDS1B6qj5gp/OWDRhcExY7rfPTbY0Y1unuS4N8+C4dO1sFDANKSwl5tDfrs1ZN99J8H24jO9TjB0EPAAezxO8/DyjPRhe0wiBunObz0iiyVK73APoHJ1atCQ8cjKXUipCELpvog5k+XAdVwBeLb6N+Yw9LNUCMlIMXalj2koZ6IwbMY687qx2XlSgIH11pZC8ArRg82CCW/zi5gYckbeWVkC75ne/O3q3wd7h8/t8rdD/62hIyucV68udIFW7amCSN8/XFQ==

运行后出现上述解码错误。

解决方案

修改Dart端解密逻辑,正确处理密文的Base64解码以及明文的二次Base64解码:

String server_response = serverResponse.substring(9);
print(server_response);
final Uint8List cipherText = base64Decode(server_response);
final decrypted = rsaDecrypt(my_private, cipherText);
final decoded = utf8.decode(decrypted);
final b64Decoded = base64Decode(decoded);
print(decoded);
print(utf8.decode(b64Decoded));

补充说明

问题根源在于Python端对明文进行了Base64编码后再加密,因此Dart端解密后需要先将结果转为字符串,再进行一次Base64解码才能得到原始明文。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 07:20:36