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

Android与纯Java的RSA/OAEP加密解密不兼容问题求助

解决Android RSA OAEP加密与纯Java解密不兼容的问题

你遇到的核心问题是Android和标准Java对RSA OAEP填充的默认参数实现不一致,导致加密解密无法匹配。虽然PKCS1Padding因为参数简单能正常工作,但OAEP涉及哈希函数和MGF1参数的默认值差异,这是解密失败的关键。

问题根源

Android的Cipher.getInstance("RSA/ECB/OAEPWithAndMGF1Padding")其实是RSA/ECB/OAEPWithSHA-1AndMGF1Padding的简写,而标准Java环境中,这个简写对应的默认哈希算法可能和Android不一致(比如部分Java版本默认使用SHA-256,或者对算法字符串的解析逻辑不同)。即使你尝试指定RSA/ECB/OAEPWithSHA-256AndMGF1Padding,如果没有明确指定参数,两端的Cipher仍可能使用不同的MGF1参数细节,导致解密失败。

解决方案:强制统一OAEP参数

要解决这个问题,需要在两端明确指定完整的OAEP参数,消除默认值的歧义。以下是修改后的代码:

Android端加密代码(修改后)

import android.util.Base64;
import java.security.spec.MGF1ParameterSpec;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;

public static String encryptMessage(final String plainText, final PublicKey publicKey) throws Exception {
    // 使用完整的算法名称,同时手动指定参数确保一致性
    Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
    
    // 明确指定OAEP的哈希算法、MGF1算法及参数,与Java端完全对齐
    OAEPParameterSpec oaepParams = new OAEPParameterSpec(
        "SHA-256", 
        "MGF1", 
        MGF1ParameterSpec.SHA256, 
        PSource.PSpecified.DEFAULT
    );
    
    cipher.init(Cipher.ENCRYPT_MODE, publicKey, oaepParams);
    return Base64.encodeToString(cipher.doFinal(plainText.getBytes()), Base64.NO_WRAP);
}

纯Java端解密代码(修改后)

import java.util.Base64;
import java.security.spec.MGF1ParameterSpec;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;

public static String decryptMessage(final String encryptedText, final PrivateKey privateKey) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
    
    // 与Android端完全相同的OAEP参数配置
    OAEPParameterSpec oaepParams = new OAEPParameterSpec(
        "SHA-256", 
        "MGF1", 
        MGF1ParameterSpec.SHA256, 
        PSource.PSpecified.DEFAULT
    );
    
    cipher.init(Cipher.DECRYPT_MODE, privateKey, oaepParams);
    Base64.Decoder decoder = Base64.getDecoder();
    byte[] byteArray = decoder.decode(encryptedText);
    byte[] decryptedArray = cipher.doFinal(byteArray);
    String plainText = new String(decryptedArray);
    return plainText;
}

额外排查点

  1. 验证Base64一致性:虽然你用PKCS1Padding能正常解密,说明Base64编码解码没有问题,但可以临时打印加密后的字符串,对比Android端输出和Java端接收的字符串是否完全一致,排除传输过程中的编码损坏。
  2. 确认密钥配对:确保加密用的公钥和解密用的私钥是同一密钥对生成的(这点你用PKCS1能解密已经基本验证,但可以再确认一次)。
  3. JCE支持性:如果使用SHA-256以外的哈希算法,需要确保两端的JCE(Java加密扩展)都支持该算法(SHA-256是主流环境都支持的,一般没问题)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:32:45