如何在Node.js中使用Base64格式的RSA公钥进行加密?
Hey there! I totally get the frustration when you can't find a straightforward solution for cross-platform RSA stuff. Let's fix this together—here's a step-by-step guide to get your Node.js server encrypting data using that Base64 public key from your Android app.
First, let's confirm what your Android code is probably doing (since your snippet cut off). Typically, when you generate an RSA key pair in Android and export the public key to Base64, you're getting the X.509 DER-encoded public key as a Base64 string. Node.js's crypto module can work with this, but we need to convert it into a format the module understands first.
Step 1: Your Android Key Generation (Reference)
Just to make sure we're on the same page, here's what your complete key generation code might look like:
import java.security.KeyPair; import java.security.KeyPairGenerator; import java.util.Base64; public class RSAKeyGenerator { public static void main(String[] args) throws Exception { // Initialize RSA key pair generator with 2048-bit keys (secure standard) KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048); KeyPair keyPair = keyGen.generateKeyPair(); // Export public key as Base64 string String base64PublicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); System.out.println("Base64 Public Key: " + base64PublicKey); } }
Step 2: Node.js Server Code to Encrypt Data
Now, here's the Node.js code to take that Base64 public key, process it, and encrypt your data. We'll use the built-in crypto module (no external dependencies needed):
const crypto = require('crypto'); /** * Encrypts plaintext using a Base64-encoded RSA public key from Android * @param {string} base64PublicKey - Base64 string of Android's RSA public key * @param {string} plaintext - Data to encrypt (UTF-8 string) * @returns {string} Base64-encoded encrypted data (easy to send to Android) */ function encryptWithAndroidPublicKey(base64PublicKey, plaintext) { try { // Decode the Base64 string to a Buffer (matches Android's DER format) const publicKeyBuffer = Buffer.from(base64PublicKey, 'base64'); // Create a PublicKey object from the DER buffer // 'spki' refers to the X.509 public key format (what Android exports) const publicKey = crypto.createPublicKey({ key: publicKeyBuffer, format: 'der', type: 'spki' }); // Encrypt the data—critical: match padding with your Android app! // Use RSA_PKCS1_OAEP_PADDING if your Android code uses OAEP padding const encryptedBuffer = crypto.publicEncrypt({ key: publicKey, padding: crypto.constants.RSA_PKCS1_PADDING, // Uncomment below if using OAEP padding: // oaepHash: 'sha256' }, Buffer.from(plaintext, 'utf8')); // Convert encrypted buffer back to Base64 for easy transmission return encryptedBuffer.toString('base64'); } catch (error) { console.error("Encryption failed:", error); throw error; } } // Example usage const androidBase64Key = "YOUR_ANDROID_BASE64_PUBLIC_KEY_HERE"; const dataToSend = "Sensitive data from server to Android client"; const encryptedData = encryptWithAndroidPublicKey(androidBase64Key, dataToSend); console.log("Encrypted Data (Base64):", encryptedData);
Critical Notes to Avoid Headaches
- Matching Padding: This is the #1 cause of decryption failures! If your Android app uses OAEP padding (e.g.,
Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding")), update the Node.js code to usecrypto.constants.RSA_PKCS1_OAEP_PADDINGand specify the correct hash (likesha256). - Key Length: Stick to the same key length on both platforms (2048 bits is secure and standard; avoid 1024-bit keys—they're no longer safe).
- Character Encoding: We're using UTF-8 for the plaintext—make sure your Android app decodes the encrypted data using the same encoding.
Quick Reference: Decrypt on Android
Just in case you need it, here's how your Android app can decrypt the Node.js-encrypted data:
import java.security.PrivateKey; import javax.cipher.Cipher; import java.util.Base64; public class RSADecryptor { public static String decrypt(String base64EncryptedData, PrivateKey privateKey) throws Exception { // Match padding to what you used in Node.js Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] encryptedBytes = Base64.getDecoder().decode(base64EncryptedData); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, "UTF-8"); } }
That should cover everything you need to get this working smoothly. Let me know if you hit any snags!
内容的提问来源于stack exchange,提问作者user9275630

