Generate and sign messages with RSA in Java

Generate and sign messages with RSA in Java

RSA stands for Rivest Shamir Adleman. It is one of the oldest yet most widely used. RSA is a public-key cryptosystem that is suitable for transmitting data securely. In this article, we cover how to generate and sign messages with RSA in Java.

How RSA works

When generating an RSA, a key pair is generated, a public and a private key. One can encrypt (with a private key) and decrypt (with a public key) messages with those keys. However, that’s insecure and is not how RSA should be used.

Instead, a message should be signed with a private key. That generates a signature that can be used to verify the message alongside the public key.

To understand the components of the RSA and their usage, have a look at the diagram below:

RSA components

The following image depicts the process of RSA, from the key generation to message verification:

RSA mechanics

Generate a key pair in Java

As stated earlier, to use RSA, we need to generate a key pair. The private key is used to sign a message, and the public key is used by the receiving party to verify the message signature (the output of signing a message with a private key is called the signature).

To generate a key pair, we can use the java.security APIs as follows:

public static KeyPair getKeyPair() throws NoSuchAlgorithmException {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(2048, new SecureRandom());
    return keyPairGenerator.generateKeyPair();
}

Sign a message with private key

Signing a message is used to verify the authenticity of the sender. To sign a message in Java, we need to use the private key portion of the key we generated in the previous step as follows:

public static String signMessage(String message, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    Signature signature = Signature.getInstance("SHA256withRSA");
    signature.initSign(privateKey);
    signature.update(message.getBytes(UTF_8));
    return Base64.getEncoder().encodeToString(signature.sign());
}

The above code generates a string signature that should be sent to the receiving party alongside the message so that the receiver can verify the authenticity of the message. Additionally, the receiver must retrieve the public key from a different trusted channel. For instance, from a public URL or endpoint.

Verify a message signature with public key

As mentioned, the receiving party can verify the message with the public key. The Java implementation of it is as follows:

public static boolean verifyMessage(String message, String signature, PublicKey publicKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
    Signature publicSignature = Signature.getInstance("SHA256withRSA");
    publicSignature.initVerify(publicKey);
    publicSignature.update(message.getBytes(UTF_8));
    return publicSignature.verify(Base64.getDecoder().decode(signature));
}

Conclusion

In this article, we discussed how to generate and sign messages with RSA in Java. First, we covered the underlying mechanics of the RSA encryption algorithm. Then, we demonstrated generating a key pair to sign and verify messages. Lastly, we provided the implementation of key pair, RSA signature generation, and verification in Java. As always, the tutorial’s code is available on the Geeky Hacker GitHub repository.

Inline/featured images credits