Flutter PointyCastle实现RSA/OAEP-SHA256加密遇在线解密填充错误
RSA/ECB/OAEPWithSHA-256AndMGF1Padding解密填充错误排查
问题背景
我用PointyCastle和encrypt库严格按文档实现了RSA/ECB/OAEPWithSHA-256AndMGF1Padding加密,本地运行正常,但在devgland.com这类在线网站测试解密时,出现Padding error in decryption(解密填充错误)。
加密代码
String rsaEncrypt(String dataToEncrypt) { final publicKey = RSAKeyParser().parse(publicKeyStr) as RSAPublicKey; final engine = OAEPEncoding.withSHA256(RSAEngine()); engine.init( true, PublicKeyParameter<RSAPublicKey>(publicKey), ); // true=encrypt return base64Encode( _processInBlocks( engine, Uint8List.fromList(dataToEncrypt.codeUnits), ), ); } Uint8List _processInBlocks(AsymmetricBlockCipher engine, Uint8List input) { final numBlocks = input.length ~/ engine.inputBlockSize + ((input.length % engine.inputBlockSize != 0) ? 1 : 0); final output = Uint8List(numBlocks * engine.outputBlockSize); var inputOffset = 0; var outputOffset = 0; while (inputOffset < input.length) { final chunkSize = (inputOffset + engine.inputBlockSize <= input.length) ? engine.inputBlockSize : input.length - inputOffset; outputOffset += engine.processBlock( input, inputOffset, chunkSize, output, outputOffset); inputOffset += chunkSize; } return (output.length == outputOffset) ? output : output.sublist(0, outputOffset); }
核心问题及解决办法
1. 错误的分块处理逻辑
RSA-OAEP是单块加密算法,不支持分块加密。你的_processInBlocks方法会破坏OAEP的填充结构,导致解密时无法验证填充。
修正方案:移除分块逻辑,直接处理整个明文(注意明文长度不能超过engine.inputBlockSize)。如果明文过长,必须使用混合加密:先用AES等对称算法加密明文,再用RSA加密对称密钥。
修正后的加密代码:
String rsaEncrypt(String dataToEncrypt) { final publicKey = RSAKeyParser().parse(publicKeyStr) as RSAPublicKey; // 显式指定OAEP和MGF1都使用SHA256 final engine = OAEPEncoding( RSAEngine(), SHA256Digest(), SHA256Digest(), Uint8List(0), // 空标签参数,和大多数在线工具保持一致 ); engine.init(true, PublicKeyParameter<RSAPublicKey>(publicKey)); final inputBytes = Uint8List.fromList(dataToEncrypt.codeUnits); // 检查输入长度是否符合OAEP限制 if (inputBytes.length > engine.inputBlockSize) { throw Exception('明文长度超过RSA-OAEP最大限制,请使用混合加密'); } final encryptedBytes = engine.processBlock(inputBytes, 0, inputBytes.length); return base64Encode(encryptedBytes); }
2. MGF1哈希算法不匹配
OAEPEncoding.withSHA256仅指定了OAEP的哈希算法为SHA256,但PointyCastle默认给MGF1用的是SHA-1。而多数在线解密工具默认会用SHA256作为MGF1的哈希算法,导致算法参数不匹配,触发填充错误。
修正方案:初始化OAEPEncoding时显式指定MGF1的哈希算法为SHA256,如上修正代码所示。
3. 密钥格式不兼容
确保在线工具使用的私钥和你的公钥是配对密钥,且密钥格式一致:
- 检查公钥是否为PKCS#8格式(PointyCastle的
RSAKeyParser默认支持),如果在线工具要求PKCS#1格式,需要转换密钥格式; - 确认私钥没有额外的密码保护,多数在线工具不支持解密带密码的私钥。
内容的提问来源于stack exchange,提问作者user9979173
相关产品推荐
相关产品推荐

