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> |
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.
|
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\.
|
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 |
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(privateKey, RSA_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(publicKey, RSA_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
- 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.
1 Comments