Cryptography — Sign payload, Encrypt a plain text password and Decrypt it

Srikanth Dannarapu
Javarevisited
Published in
4 min readMar 13, 2023

--

Sign payload or any String:

To sign a payload/String using a public key in Java, you can follow these steps:

  1. Generate a key pair: First, you need to generate a key pair consisting of a public key and a private key. You can use the Java KeyPairGenerator class to do this.
  2. Sign the payload: Once you have the private key, you can use it to sign the payload. You can use the Java Signature class to do this. The Signature class provides different algorithms to sign data, such as SHA256withRSA, SHA1withDSA, etc. Choose the appropriate algorithm based on your requirements.
  3. Send the signed payload and the public key to the client: The client needs to have access to the public key to verify the signature. You can send the signed payload and the public key to the client through a REST endpoint or any other means.
  4. Verify the signature: Once the client receives the signed payload and the public key, it can use the public key to verify the signature. You can use the Java Signature class to verify the signature.

Below is an example code snippet that demonstrates how to sign a payload and verify it using a public key:

import java.security.*;

public class Main {
public static void main(String[] args) throws Exception {
String payload = "test-payload";
// Generate key pair
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();

// Sign the payload
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(payload.getBytes());
byte[] signedPayload = signature.sign();

// Verify the signature
Signature verifier = Signature.getInstance("SHA256withRSA");
verifier.initVerify(publicKey);
verifier.update(payload.getBytes());
boolean verified = verifier.verify(signedPayload);
if (verified) {
// Signature is valid
System.out.println("valid");
} else {
// Signature is invalid
System.out.println("invalid");
}

}
}

Store private and public keys in a keystore and trust store files:

To store private and public keys in a keystore and trust store files with passwords in a Java application, and to retrieve them to encrypt and decrypt a string, you can follow these steps:

  1. Create a keystore file: You can create a keystore file using the keytool command-line tool that comes with the Java Development Kit (JDK).
keytool -genkeypair -alias mykey -keyalg RSA -keysize 2048 -keystore mykeystore.jks

This command generates a new RSA key pair with an alias mykey and stores it in a new keystore file mykeystore.jks.

2. Create a trust store file: You can create a trust store file using the keytool command-line tool as well.

keytool -import -alias mykey -file mycertificate.crt -keystore mytruststore.jks

This command imports the certificate of the key pair that you created in step 1 into a new trust store file mytruststore.jks.

3. Load the keystore and trust store files in your Java application: You can use the Java KeyStore class to load the keystore and trust store files in your application.

KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream("mykeystore.jks"), "keystore_password".toCharArray());

KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("mytruststore.jks"), "truststore_password".toCharArray());

In this example, we are loading the keystore and trust store files into two separate KeyStore objects using the JKS format. You need to provide the correct passwords for the keystore and trust store files.

4. Retrieve the private key and public key from the keystore: You can use the Java KeyStore class to retrieve the private key and public key from the keystore.

Key privateKey = keyStore.getKey("mykey", "key_password".toCharArray());
PublicKey publicKey = keyStore.getCertificate("mykey").getPublicKey();

In this example, we are retrieving the private key with the alias mykey and its corresponding password, and the public key from the keystore.

5. Encrypt and decrypt a string using the keys: You can use the Java Cipher class to encrypt and decrypt a string using the private key and public key.

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal("Hello, world!".getBytes());

cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = cipher.doFinal(encryptedData);
String decryptedString = new String(decryptedData);

In this example, we are encrypting the string “Hello, world!” using the public key, and decrypting the encrypted data using the private key.

Note: The above code snippets are for demonstration purposes only and may require additional error handling and security measures in a production environment.

Complete example that demonstrates how to encrypt and decrypt a string using RSA encryption

import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class EncryptionExample {

public static void main(String[] args) throws Exception {

// Load Bouncy Castle provider
Security.addProvider(new BouncyCastleProvider());

// Load keystore and truststore
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream("mykeystore.jks"), "keystore_password".toCharArray());

KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("mytruststore.jks"), "truststore_password".toCharArray());

// Retrieve private and public keys from keystore
PrivateKey privateKey = (PrivateKey) keyStore.getKey("mykey", "key_password".toCharArray());
PublicKey publicKey = trustStore.getCertificate("mykey").getPublicKey();

// Encrypt data using public key
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal("Hello, world!".getBytes());

// Decrypt data using private key
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = cipher.doFinal(encryptedData);
String decryptedString = new String(decryptedData);

System.out.println("Original string: Hello, world!");
System.out.println("Encrypted data: " + new String(encryptedData));
System.out.println("Decrypted string: " + decryptedString);
}
}

In this example, we are using the Bouncy Castle provider for RSA encryption and decryption. We first load the keystore and truststore files using the KeyStore class. We then retrieve the private key and public key from the keystore file. We use the public key to encrypt the string “Hello, world!” using the RSA/ECB/PKCS1Padding algorithm. We then use the private key to decrypt the encrypted data back to the original string.

below is the Maven dependency required for this example:

<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
</dependencies>

Thanks, before you go:

  • 👏 Please clap for the story and follow the author 👉
  • Please share your questions or insights in the comments section below. Let’s help each other and become better Java developers.
  • Let’s connect on LinkedIn

--

--