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

将Python pyCrypto PKCS1 OAEP解密逻辑转换为Java Cipher实现

Converting PyCrypto PKCS1_OAEP Decryption to Android Java

Got it, let's walk through translating that PyCrypto PKCS1_OAEP decryption logic to Android Java step by step. I've dealt with this exact cross-language crypto mismatch a few times, so here's what you need to get right:

First, Understand the Python Baseline

Your Python code is likely doing something like this (based on PKCS1_OAEP.new):

from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

# Load RSA private key
private_key = RSA.import_key(open("private_key.pem").read())
# Initialize OAEP decryptor (defaults: SHA-1 for hash + MGF1, empty PSource)
cipher = PKCS1_OAEP.new(private_key)
# Decrypt ciphertext bytes
decrypted_data = cipher.decrypt(encrypted_bytes)

We need to mirror these exact defaults in Java—any parameter mismatch will cause decryption to fail silently or throw errors.


Step 1: Load Your RSA Private Key in Android

First, handle loading your private key. If you're using a PEM-formatted key (like the one in Python), clean up the headers and decode from Base64:

import android.util.Base64;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

// Example PEM private key string
String privateKeyPem = "-----BEGIN RSA PRIVATE KEY-----\n" +
                       "YOUR_KEY_CONTENTS_HERE\n" +
                       "-----END RSA PRIVATE KEY-----";

// Strip PEM headers and whitespace
String cleanedPem = privateKeyPem.replace("-----BEGIN RSA PRIVATE KEY-----", "")
                                 .replace("-----END RSA PRIVATE KEY-----", "")
                                 .replaceAll("\\s", "");

// Decode Base64 to raw key bytes
byte[] privateKeyBytes = Base64.decode(cleanedPem, Base64.DEFAULT);

// Generate PrivateKey object (works for PKCS#8 formatted keys)
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

Note: If your key is in PKCS#1 format (common in PyCrypto), convert it to PKCS#8 first, or use the BouncyCastle provider to load PKCS#1 directly (more on that later).


Step 2: Configure Cipher for OAEP Decryption

Mirror PyCrypto's OAEP parameters exactly in Java:

import javax.crypto.Cipher;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import java.security.spec.MGF1ParameterSpec;
import java.nio.charset.StandardCharsets;

// Define OAEP params to match PyCrypto's defaults
OAEPParameterSpec oaepParams = new OAEPParameterSpec(
    "SHA-1",          // Main hash algorithm
    "MGF1",           // Mask generation function
    MGF1ParameterSpec.SHA1,  // MGF1 hash algorithm (matches main hash)
    PSource.PSpecified.DEFAULT  // Empty PSource (PyCrypto's default)
);

// Get cipher instance with correct algorithm string
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");

// Initialize for decryption with private key + OAEP params
cipher.init(Cipher.DECRYPT_MODE, privateKey, oaepParams);

// Decrypt your ciphertext (replace encryptedBytes with your actual byte array)
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

// Convert to string if needed (adjust charset to match your data)
String decryptedText = new String(decryptedBytes, StandardCharsets.UTF_8);

Step 3: Handle Non-Default Configurations

If your Python code uses a different hash (e.g., SHA-256), update the parameters accordingly:

  • Swap "SHA-1" with "SHA-256" in OAEPParameterSpec
  • Use MGF1ParameterSpec.SHA256 instead of SHA1
  • Update the cipher algorithm string to "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"

Step 4: Fix Provider Compatibility Issues

If you hit NoSuchAlgorithmException, use the BouncyCastle provider (it's more flexible for RSA OAEP variants):

  1. Add it to your app's build.gradle:
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
  1. Register the provider before using the cipher:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;

// Add this once (e.g., in your Application class)
Security.addProvider(new BouncyCastleProvider());

// Get cipher with BouncyCastle provider
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", "BC");

Critical Tips to Avoid Failure

  • Parameter Exactness: The hash, MGF1 hash, and PSource must match between Python and Java. Even a tiny difference (SHA-1 vs SHA-256) will break decryption.
  • Key Formats: PyCrypto handles PKCS#1 and PKCS#8 keys seamlessly, but Java's default only supports PKCS#8. Convert PKCS#1 keys or use BouncyCastle.
  • Byte Consistency: Ensure the ciphertext byte array is passed correctly (no accidental encoding mismatches between Python and Java).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:50:04