Header Ads Widget

Responsive Advertisement

Asymmetric Encryption: Public Key for Encryption, Private for Decryption

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:

  1. Symmetric Encryption: The same key is used for both encryption and decryption.
  2. 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

  1. Generate RSA Key Pair: This includes a public key and a private key.
  2. Encrypt Data Using Public Key: This is typically done by a third party.
  3. 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

  1. 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.

  1. 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.

  1. 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
Asymmetric Encryption










Post a Comment

0 Comments