In asymmetric encryption, a common scenario involves
encrypting data using a public key and decrypting it using a private key. This
can be particularly useful when dealing with file encryption where a third
party can use your public key to encrypt a file, and only you can decrypt it
using your private key. It looks like there is a mix-up between symmetric and
asymmetric encryption in your request. Let's clarify both:
- Symmetric
Encryption: The same key is used for both encryption and decryption.
- Asymmetric
Encryption: Two different keys are used: a public key for encryption
and a private key for decryption.
The scenario you described fits asymmetric encryption where
you use a public key to encrypt data and a private key to decrypt it.
Let's go through an example of asymmetric encryption using
RSA in Java:
Asymmetric Encryption Example Using RSA
- Generate
RSA Key Pair: This includes a public key and a private key.
- Encrypt
Data Using Public Key: This is typically done by a third party.
- Decrypt
Data Using Private Key: This is done by the owner of the private key.
Maven Dependencies
Add the following dependencies to your pom.xml:
xml
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
</dependencies>
|
Java Code Example
java
package com.kartik;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
/**
*
* @author kartik
* RSA - Encrypt Data using Public Key
* RSA - Descypt Data using Private Key
*/
public class RSAEncryptDescrypt {
private static final String PUBLIC_KEY_FILE = "Public.key";
private static final String PRIVATE_KEY_FILE = "Private.key";
public static void main(String[] args) throws IOException {
try {
System.out.println("-------GENRATE PUBLIC and PRIVATE
KEY-------------");
KeyPairGenerator keyPairGenerator =
KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); //1024 used for normal
securities
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
System.out.println("Public Key - " + publicKey);
System.out.println("Private Key - " + privateKey);
//Pullingout parameters which makes up Key
System.out.println("\n------- PULLING OUT PARAMETERS WHICH
MAKES KEYPAIR----------\n");
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec rsaPubKeySpec =
keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);
RSAPrivateKeySpec rsaPrivKeySpec =
keyFactory.getKeySpec(privateKey, RSAPrivateKeySpec.class);
System.out.println("PubKey Modulus : " +
rsaPubKeySpec.getModulus());
System.out.println("PubKey Exponent : " +
rsaPubKeySpec.getPublicExponent());
System.out.println("PrivKey Modulus : " +
rsaPrivKeySpec.getModulus());
System.out.println("PrivKey Exponent : " +
rsaPrivKeySpec.getPrivateExponent());
//Share public key with other so they can encrypt data and
decrypt thoses using private key(Don't share with Other)
System.out.println("\n--------SAVING PUBLIC KEY AND PRIVATE
KEY TO FILES-------\n");
RSAEncryptDescrypt rsaObj = new RSAEncryptDescrypt ();
rsaObj.saveKeys(PUBLIC_KEY_FILE, rsaPubKeySpec.getModulus(),
rsaPubKeySpec.getPublicExponent());
rsaObj.saveKeys(PRIVATE_KEY_FILE, rsaPrivKeySpec.getModulus(),
rsaPrivKeySpec.getPrivateExponent());
//Encrypt Data using Public Key
byte[] encryptedData = rsaObj.encryptData("Kartik mandal -
Classified Information !");
//Descypt Data using Private Key
rsaObj.decryptData(encryptedData);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}catch (InvalidKeySpecException e) {
e.printStackTrace();
}
}
/**
* Save Files
* @param fileName
* @param mod
* @param exp
* @throws IOException
*/
private void saveKeys(String fileName,BigInteger mod,BigInteger exp)
throws IOException{
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
System.out.println("Generating "+fileName +
"...");
fos = new FileOutputStream(fileName);
oos = new ObjectOutputStream(new BufferedOutputStream(fos));
oos.writeObject(mod);
oos.writeObject(exp);
System.out.println(fileName + " generated
successfully");
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(oos != null){
oos.close();
if(fos != null){
fos.close();
}
}
}
}
/**
* Encrypt Data
* @param data
* @throws IOException
*/
private byte[] encryptData(String data) throws IOException {
System.out.println("\n----------------ENCRYPTION
STARTED------------");
System.out.println("Data Before Encryption :" + data);
byte[] dataToEncrypt = data.getBytes();
byte[] encryptedData = null;
try {
PublicKey pubKey = readPublicKeyFromFile(PUBLIC_KEY_FILE);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
encryptedData = cipher.doFinal(dataToEncrypt);
System.out.println("Encryted Data: " + encryptedData);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("----------------ENCRYPTION
COMPLETED------------");
return encryptedData;
}
/**
* Encrypt Data
* @param data
* @throws IOException
*/
private void decryptData(byte[] data) throws IOException {
System.out.println("\n----------------DECRYPTION
STARTED------------");
byte[] descryptedData = null;
try {
PrivateKey privateKey =
readPrivateKeyFromFile(PRIVATE_KEY_FILE);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
descryptedData = cipher.doFinal(data);
System.out.println("Decrypted Data: " + new
String(descryptedData));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("----------------DECRYPTION
COMPLETED------------");
}
/**
* read Public Key From File
* @param fileName
* @return PublicKey
* @throws IOException
*/
public PublicKey readPublicKeyFromFile(String fileName) throws
IOException{
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(new File(fileName));
ois = new ObjectInputStream(fis);
BigInteger modulus = (BigInteger) ois.readObject();
BigInteger exponent = (BigInteger)
ois.readObject();
//Get Public Key
RSAPublicKeySpec rsaPublicKeySpec = new
RSAPublicKeySpec(modulus, exponent);
KeyFactory fact =
KeyFactory.getInstance("RSA");
PublicKey publicKey =
fact.generatePublic(rsaPublicKeySpec);
return publicKey;
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(ois != null){
ois.close();
if(fis != null){
fis.close();
}
}
}
return null;
}
/**
* read Public Key From File
* @param fileName
* @return
* @throws IOException
*/
public PrivateKey readPrivateKeyFromFile(String fileName) throws
IOException{
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(new File(fileName));
ois = new ObjectInputStream(fis);
BigInteger modulus = (BigInteger) ois.readObject();
BigInteger exponent = (BigInteger)
ois.readObject();
//Get Private Key
RSAPrivateKeySpec rsaPrivateKeySpec = new
RSAPrivateKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey privateKey =
fact.generatePrivate(rsaPrivateKeySpec);
return privateKey;
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(ois != null){
ois.close();
if(fis != null){
fis.close();
}
}
}
return null;
}
}
|
Explanation
- KeyPair
Generation:
Ø
The generateRSAKeyPair method generates an RSA
key pair (public and private keys).
Ø
KeyPairGenerator.getInstance("RSA",
"BC") initializes the key pair generator with the RSA algorithm and
BouncyCastle provider.
Ø
keyPairGenerator.initialize(2048) sets the key
size to 2048 bits for strong security.
- Encryption:
Ø
The encrypt method takes the data and a public
key to encrypt the data.
Ø
Cipher.getInstance("RSA/ECB/PKCS1Padding",
"BC") initializes the cipher with RSA algorithm, ECB mode, and PKCS1
padding using BouncyCastle provider.
Ø
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
initializes the cipher for encryption mode.
Ø
cipher.doFinal(data.getBytes()) performs the
encryption and returns the encrypted byte array, which is then encoded to a
Base64 string.
- Decryption:
Ø
The decrypt method takes the encrypted data and
a private key to decrypt the data.
Ø
Cipher.getInstance("RSA/ECB/PKCS1Padding",
"BC") initializes the cipher with RSA algorithm, ECB mode, and PKCS1
padding using BouncyCastle provider.
Ø
cipher.init(Cipher.DECRYPT_MODE, privateKey)
initializes the cipher for decryption mode.
Ø
cipher.doFinal(Base64.getDecoder().decode(encryptedData))
performs the decryption and returns the original byte array, which is then
converted to a string.
Notes
Ø Key
Management: Proper management of private keys is crucial to maintain
security. Private keys should be stored securely and not exposed.
Ø Padding
and Mode: RSA/ECB/PKCS1Padding is used in this example. Depending on the
use case, different padding schemes and modes might be required.
Ø BouncyCastle
Provider: BouncyCastle is a widely used cryptography library in Java that
provides various cryptographic algorithms and functions.
This example demonstrates the basic usage of RSA encryption
and decryption using a public-private key pair in Java.
 |
Asymmetric Encryption |
0 Comments