如何用RSA公钥签名消息?JS实现正确性及公钥加密求助
Hey there! I’ve built RSA signing and public-key encryption in JavaScript with jsrsasign plenty of times, so let’s break this down for you—first, let’s clear up a common mix-up, then walk through correct implementations you can compare yours against.
First: Don’t Mix Up Signing & Encryption
You mentioned "using an RSA public key to sign a message"—that’s an easy mistake to make! Let’s clarify:
- RSA Signing: Uses a private key to sign a message (we actually sign a hash of the message). Anyone with your public key can verify the message came from you and hasn’t been tampered with.
- RSA Public-Key Encryption: Uses a public key to encrypt a message. Only the owner of the corresponding private key can decrypt it.
If you were trying to sign, you’ll want to swap to using your private key for the signing step—let’s show you how that works correctly.
Correct RSA Signing Implementation
Here’s a solid, secure example using SHA-256 (avoid weak algorithms like SHA-1!):
// Your RSA private key (PEM format—make sure it's properly formatted!) const privateKeyPem = `-----BEGIN RSA PRIVATE KEY----- ... Your private key content here ... -----END RSA PRIVATE KEY-----`; const message = "This is the message I want to sign"; // 1. Initialize signature object with SHA256 + RSA const sig = new KJUR.crypto.Signature({ alg: "SHA256withRSA" }); // 2. Load your private key to sign with sig.init(privateKeyPem); // 3. Feed the message into the signature object sig.updateString(message); // 4. Generate the signature (returns Base64 string) const signature = sig.sign(); console.log("Generated Signature:", signature); // ------------------------------ // Verify the signature (using public key) // ------------------------------ const publicKeyPem = `-----BEGIN PUBLIC KEY----- ... Your public key content here ... -----END PUBLIC KEY-----`; const verifier = new KJUR.crypto.Signature({ alg: "SHA256withRSA" }); verifier.init(publicKeyPem); verifier.updateString(message); // Check if the signature is valid (returns true/false) const isSignatureValid = verifier.verify(signature); console.log("Signature Valid?", isSignatureValid);
RSA Public-Key Encryption Example
If your goal is actually encrypting a message with a public key (so only the private key owner can read it), here’s how to do that securely with OAEP padding (safer than the older PKCS#1 v1.5):
const publicKeyPem = `-----BEGIN PUBLIC KEY----- ... Your public key content here ... -----END PUBLIC KEY-----`; const plaintextMessage = "This is a secret message only the private key holder can read"; // 1. Initialize encryption object with RSA-OAEP const encryptor = new KJUR.crypto.Cipher({ alg: "RSAES-OAEP", prov: "cryptojs/jsrsa", key: publicKeyPem }); // 2. Encrypt the message (outputs Base64) const encryptedMessage = encryptor.doFinal(plaintextMessage, "utf8", "base64"); console.log("Encrypted Message:", encryptedMessage); // ------------------------------ // Decrypt with private key // ------------------------------ const decryptor = new KJUR.crypto.Cipher({ alg: "RSAES-OAEP", prov: "cryptojs/jsrsa", key: privateKeyPem }); const decryptedMessage = decryptor.doFinal(encryptedMessage, "base64", "utf8"); console.log("Decrypted Message:", decryptedMessage);
Quick Checks for Your Implementation
- Key Format: Double-check your PEM keys—no extra spaces, missing headers/footers, or formatting errors will break jsrsasign’s parsing.
- Message Length for Encryption: RSA has a hard length limit (e.g., 2048-bit keys can encrypt ~245 bytes max). For longer messages, use hybrid encryption: encrypt the message with AES, then encrypt the AES key with RSA.
- Algorithm Choice: Stick to SHA-256/384/512 for signing, and RSAES-OAEP for encryption—these are modern, secure choices.
内容的提问来源于stack exchange,提问作者alex.mironov

