Header Ads Widget

Responsive Advertisement

public key encryption and private key decryption with keystore file



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>

 

How to do:

Open an Administrator command prompt.

Press the Win key, type cmd.exe, and press Ctrl + Shift + Enter to run the Command Prompt as Administrator.

Execute the remaining steps from the Administrator command prompt.

Fig 1
Fig 1

 

 

Get the Keytool path in JDK for windows.

Copy that path and pest in administrator command prompt like below command

NOTE

These instructions assume that you have “keytool path” in java to C:\ProgramFiles\Java\jdk 1.7.0_67\bin\.

command prompt
command prompt

 

 

Run the below command.

NOTE

keytool -genkey -keystore "kartikKeystore.JCEKS" -alias "master_key" -validity 365 -keyalg RSA -keysize 1024 -keypass kartik -storetype jceks -storepass kartik

 

keystore generate
keystore generate

 



How to set KeyStore File in Java Home path :

After getting keystore file pest in any drive local C: or D: or E:

I put in D drive so my file path is D:\kartikKeystore.JCEKS

How to set this keystore file in java path

Control Panel à System and Security à System à Advanced System Settings à Advance à Environment Variable à click user variables New button à give the variable name as keyStore and variable value as D:\kartikKeystore.JCEKS à ok --. After then finished.

After then variable name as keyStore you can use in your program.

String keyStoreFilename = System.getProperty("keyStore ") if it is not working then flow below command

Map<String, String> env = System.getenv();

keyStoreFilename = env.get("keyStore");

 

java

package com.kartik.encryption;

import java.io.File;

import java.io.FileInputStream;

import java.security.InvalidAlgorithmParameterException;

import java.security.InvalidKeyException;

import java.security.Key;

import java.security.KeyFactory;

import java.security.KeyStore;

import java.security.KeyStoreException;

import java.security.NoSuchAlgorithmException;

import java.security.Provider;

import java.security.PublicKey;

import java.security.Security;

import java.security.cert.X509Certificate;

import java.util.Map;

import javax.crypto.BadPaddingException;

import javax.crypto.Cipher;

import javax.crypto.IllegalBlockSizeException;

import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.binary.Base64;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**

 * 

 * @author kartik 

 * This is How to use keystore file encryption and decryption with create public and private key

 

 */



public class Encryptor {

      private static final String JCEKS = "JCEKS";

      public static final String RSA_CIPHER_TRANSFORMATION = "RSA";

      private static String keyStoreFilename = null;

      private static String keyStorePassword = null;

      public static String ALIAS = "master_key";

      public static final byte[] IV = { 90, 10, 15, 125, 112, -92, 76, 102, 102,76, -92, 112, 125, 15, 10, 90 };

      private static Key privateKey;

      private static PublicKey publicKey;

      public static String RSA_ECB_PKCS5 = "RSA/ECB/PKCS1Padding";

      private static BouncyCastleProvider bcProvider = new BouncyCastleProvider();

      static {

            keyStorePassword = "kartik";//mention your keystore password

            Security.addProvider(bcProvider);

            initService();

      }

      private static Encryptor instance = new Encryptor();

      private Encryptor() {

      }

      public static Encryptor getInstance() {

            return instance;

      }

      /**

       * <b><i><font color="green">getenv</font></i> gets an environment variable.

       * <i><font color="green">getProperty</font></i> gets a Java property.

       * Environment variables are specified at the OS level. Java properties

       *  are specified by passing the -D option to the JVM (and can be set

       *   programmatically).

       *   </b>

       * Initializes Master key based encryption Service

       */

      public static void initService() {

            KeyStore keyStore = null;

            try {

                  if (keyStoreFilename == null) {

                         

                          Map<String, String> env = System.getenv();

                          keyStoreFilename = env.get("keyStore");

                        // keyStoreFilename = System.getProperty("KARTIK_KEYSTORE");

                        //keyStoreFilename = "d:\\kartikKeystore.JCEKS";

                        if (keyStoreFilename == null) {

                              System.out

                                          .println("ERROR: Please provide key store " +

                                                      "location full path! Example " +

                                                      "/opt/java/kartikKeystore");

                              System.exit(1);

                        }

                  }

                  if (keyStoreFilename != null && keyStoreFilename.length() > 0) {

                        File file = new File(keyStoreFilename);

                        keyStore = KeyStore.getInstance(JCEKS);

                        if (file.exists()) {

                              FileInputStream input = new FileInputStream(file);

                              if (keyStore != null && input != null

                                          && keyStorePassword != null) {

                                    keyStore.load(input,keyStorePassword.toCharArray());

                                    input.close();

                                    privateKey = keyStore.getKey(ALIAS,

                                                keyStorePassword.toCharArray());

                                    X509Certificate cert = null;

                                    cert = (X509Certificate) keyStore.getCertificate(ALIAS);

                                    if (cert != null) {

                                          publicKey = cert.getPublicKey();

                                    }

                              }

                        } else {

                              System.out.println("ERROR: No Such file exists "

                                          + keyStoreFilename);

                        }

                  } else {

                        System.out

                                    .println("ERROR: Please provide correct key store" +

                                                " file name! Example" +

                                                " /opt/ctier/kartikKeystore");

                        System.exit(1);

                  }

            } catch (KeyStoreException keyStoreException) {

                  System.out.println("ERROR: " + keyStoreException.getMessage());

            } catch (Exception exception) {

                  System.out.println("ERROR: " + exception.getMessage());

            }

      }

      /**

       * Decrypts the value based on Master key

       *

       * @param cypher

       * @return

       */

      public String decrypt(String cypher) {

            String decryptedString = null;

            Cipher cipher = null;

            try {

                  cipher = Cipher.getInstance(RSA_ECB_PKCS5);

                  if (cipher != null) {

                        cipher.init(

                                    Cipher.DECRYPT_MODE,

                                    transformKey(privateKeyRSA_CIPHER_TRANSFORMATION,

                                                bcProvider));

                        decryptedString = new String(cipher.doFinal(Base64

                                    .decodeBase64(cypher.getBytes())));

                  }

            } catch (InvalidKeyException invalidKeyException) {

                  System.out.println("ERROR: " + invalidKeyException.getMessage());

            } catch (NoSuchAlgorithmException noSuchAlgorithmException) {

                  System.out.println("ERROR: "

                              + noSuchAlgorithmException.getMessage());

            } catch (NoSuchPaddingException noSuchPaddingException) {

                  System.out.println("ERROR: " + noSuchPaddingException.getMessage());

            } catch (IllegalBlockSizeException illegalBlockSizeException) {

                  System.out.println("ERROR: "

                              + illegalBlockSizeException.getMessage());

            } catch (BadPaddingException badPaddingException) {

                  System.out.println("ERROR: " + badPaddingException.getMessage());

            } catch (InvalidAlgorithmParameterException invalidAlgorithmParameterException) {

                  System.out.println("ERROR: "

                              + invalidAlgorithmParameterException.getMessage());

            } catch (Exception exception) {

                  System.out.println("ERROR: " + exception.getMessage());

            } finally {

                  cipher = null;

            }

            return decryptedString;

      }

      /**

       * Encrypts the value mased on master key

       *

       * @param plainText

       * @return

       */

      public String encrypt(String plainText) {

            String encryptedString = null;

            Cipher cipher = null;

            try {

                  cipher = Cipher.getInstance(RSA_ECB_PKCS5);

                  if (cipher != null) {

                        cipher.init(

                                    Cipher.ENCRYPT_MODE,

                                    transformKey(publicKeyRSA_CIPHER_TRANSFORMATION,

                                                bcProvider));

                        // Hexe

                        encryptedString = new String(Base64.encodeBase64(cipher

                                    .doFinal(plainText.getBytes())));

                  }

            } catch (InvalidKeyException invalidKeyException) {

                  System.out.println("ERROR: " + invalidKeyException.getMessage());

            } catch (NoSuchAlgorithmException noSuchAlgorithmException) {

                  System.out.println("ERROR: "

                              + noSuchAlgorithmException.getMessage());

            } catch (NoSuchPaddingException noSuchPaddingException) {

                  System.out.println("ERROR: " + noSuchPaddingException.getMessage());

            } catch (IllegalBlockSizeException illegalBlockSizeException) {

                  System.out.println("ERROR: "

                              + illegalBlockSizeException.getMessage());

            } catch (BadPaddingException badPaddingException) {

                  System.out.println("ERROR: " + badPaddingException.getMessage());

            } catch (InvalidAlgorithmParameterException invalidAlgorithmParameterException) {

                  System.out.println("ERROR: "

                              + invalidAlgorithmParameterException.getMessage());

            } catch (Exception exception) {

                  System.out.println("ERROR: " + exception.getMessage());

            } finally {

                  cipher = null;

            }

            return encryptedString;

      }

      /**

       * Transforms the key

       *

       * @param key

       * @param algorithm

       * @param provider

       * @return

       * @throws Exception

       */

      private static Key transformKey(Key key, String algorithm, Provider provider)

                  throws Exception {

            Key transformedKey = null;

            KeyFactory keyFactory = KeyFactory.getInstance(algorithm, provider);

            if (keyFactory != null) {

                  transformedKey = keyFactory.translateKey(key);

            }

            return transformedKey;

      }

     

      /**

       * Encrypted value started as

       * {@code static final String ENCRYPTED_VALUE_PREFIX = "ENC("}

       */

      private static final String ENCRYPTED_VALUE_PREFIX = "ENC(";

      /**

       * Encrypted value ended as

       * {@code static final String ENCRYPTED_VALUE_SUFFIX = ")"}

       */

      private static final String ENCRYPTED_VALUE_SUFFIX = ")";

      /**

       * {@code static boolean isEncryptedValue(final String value)}

       *

       * @param value

       *            value

       * @return true or false

       */

      public static boolean isEncryptedValue(final String value) {

            if (value == null) {

                  return false;

            }

            final String trimmedValue = value.trim();

            return (trimmedValue.startsWith(ENCRYPTED_VALUE_PREFIX) && trimmedValue

                        .endsWith(ENCRYPTED_VALUE_SUFFIX));

      }

      /**

       * {@code static String getInnerEncryptedValue(final String value)}

       *

       * @param value

       *            value

       * @return only encrypted value get

       */

      private static String getInnerEncryptedValue(final String value) {

            return value.substring(ENCRYPTED_VALUE_PREFIX.length(),

                        (value.length() - ENCRYPTED_VALUE_SUFFIX.length()));

      }

      public static void main(String... args) {

            String password = "Java!";

            Encryptor e = new Encryptor();

            String encryption = e.encrypt(password);

            encryption="ENC(" + encryption + ")";

            System.out.println("Password encryption --->>>>>" + encryption);

            boolean flag = isEncryptedValue(encryption);

            String dencryption =null;

            if (flag) {

                  dencryption = e.decrypt(getInnerEncryptedValue(encryption));

            }else{

             dencryption = e.decrypt(encryption);

            }

            System.out.println("Decrypted password --->>>" + dencryption);

      }

}

 

 

Output:

Password encryption --->>>>>ENC(FbzJdVeAc7cOhJDpRgIfslUayo92PDp7eaGenSju6tjw1l5u0h1MA+IS30/UShcz4Er4Z7hKuWhPJorhcfRfccN9wH55e8AtXDzH49oPEo9hJBDliHJC+J//ILuT6lmISVuYcZb2rXs6A2SNldTQJHGw3x6b1exlPUgHKgrOypQ=)

Decrypted password --->>>Java!



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.
  2. 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.
  3. 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.

Post a Comment

1 Comments

Kartik Chandra Mandal
Unknown said…
code is very easy to understand . please improve keystore generation document.