Week 143 — How can one encrypt a message using RSA?
Question of the Week #143
How can one encrypt a message using RSA?
4 Replies
RSA is an algorithm for asymmetric encryption. It allows encrypting message with a public key that can then be decrypted with a private key. Similarly, if a message is signed with the private key, it can be verified using the public key. The private and public keys are generated together and form a key pair. The public key is intended to be shared with anyone while the private key should be kept secret.
To generate a key pair consisting of a private and corresponding public key, one can obtain a
KeyPairGenerator
for RSA keys, specify the key size and then generate a KeyPair
:
The private key can be obtained using the getPrivate()
method on KeyPair
and should be kept secret. The public key can be obtained using the getPublic()
method and can be shared with anyone who should be able to encrypt or verify messages.
To actually work with messages, one can obtain a Cypher
object. That objects needs to be initialized for encryption or decryption:
After the data is encrypted with the public key as done above, it can be decrypted only using the private key. This can be done similar to decryption except that the arguments to the init
method need to be different:
Signing is the process of ensuring the integrity of a message. It is used to prove that a message has been created by some entity and has not been modified. Signing works just like encryption but using the private key. Only the entity who possesses the private key is able to encrypt message in a way such that decrypting these messages with the public key leads to the original message.
To verify the message, one can just decrypt the message using the public key.
Encrypting and decrypting large messages with RSA is slow. In practice, RSA is typically used for key exchange where the asymmetric nature of the algorithm (and its ability to be used to sign messages) is used to exchange a key for symmetric encryption (e.g. an AES key). Once both parties have exchanged the same key, they can securely communicate with each other.
On the other hand, signing large messages is typically not done by encrypting the full message with the private key. Instead, the entity signing the message computes a hash of the message, signs that with RSA (or another algorithm) and transmits both the message and the hash. The entity verifying the message decrypts the encrypted hash received from the other party. They can then computes the hash from the message as well and compare it to the decrypted hash. If they match, they can be sure that the message came from someone in posession of the private key and that the message has not been modified by someone else.
📖 Sample answer from dan1st
this will encrypt the message "very secret message" using a randomly generated RSA keypair.
output:
encrypted msg: s8Gq848C8BIpmm4dLwN8OJ/IuYq69hOV76o8D6mJdOAUK74Ms32Hlj+UQoJFJRpLnOyAkOWJkVNSBWwHRsSHqAuKmGpTJTd92uZUEq5yF0niynuTMLBtq3TiB1dECEC2iGW8NyZNkZ6gJNvVllpAnY2V3oBnrWQuhsnRAe44EQCwRG2MT5KULO9MDfNpOlQQdArtb4cjECS+UjGQRYcME1J/R5CoHKRxvEl4rMmV/FrwCEIj9l7K2il6crq5NFeie0iXodp0R48/78M3V+dPFSRUfD5K0i0UwUlfItf9my2HJYAc/95BqRDK1IivanODSw4ZSscY/Pan/37q2QGk8g==
Submission from zeeplockd
RSA is an asymmetric encryption algorithm using a pair of keys: a public key for encryption and a private key for decryption. To encrypt a message in Java, you typically use the java.security and javax.crypto libraries. Here’s an example:
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
import java.math.BigInteger;
public class RSAEncryptionExample {
public static void main(String[] args) throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048); // key size KeyPair keyPair = keyGen.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate();
String message = "Hello RSA!"; byte[] messageBytes = message.getBytes();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedBytes = cipher.doFinal(messageBytes); System.out.println("Encrypted (hex): " + bytesToHex(encryptedBytes)); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); String decryptedMessage = new String(decryptedBytes); System.out.println("Decrypted: " + decryptedMessage); } private static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02X", b)); } return sb.toString(); } }
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048); // key size KeyPair keyPair = keyGen.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate();
String message = "Hello RSA!"; byte[] messageBytes = message.getBytes();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedBytes = cipher.doFinal(messageBytes); System.out.println("Encrypted (hex): " + bytesToHex(encryptedBytes)); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); String decryptedMessage = new String(decryptedBytes); System.out.println("Decrypted: " + decryptedMessage); } private static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02X", b)); } return sb.toString(); } }
Submission from lilit0611