How to Create SHA256 RSA Signature Using Java

SHA256 with RSA signature is an efficient asymmetric encryption method used in many secure APIs. This algorithm first calculates a unique hash of the input data using SHA256 algorithm. The hash is then encrypted with a private key using the RSA algorithm. This is useful in scenarios where we only need to verify that the data is not tampered and is authentic. The original data itself is sent without encryption (usually protected by a TLS secure link). Encrypting just the hash is much faster due to its small size. For example, SHA256 with RSA is used to generate the signature part of the Google cloud storage signed URLs.

The following Java program generates a signature from an input string and a primary key in the unencrypted PKCS#8 format (If you are using Google cloud storage signed URLs, this value is in the private_key field of the downloaded JSON file)

import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

public class SHA256RSA {
    
    public static void main(String[] args) throws Exception {
        String input = "sample input";
        
        // Not a real private key! Replace with your private key!
        String strPk = "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9"
                + "w0BAQEFAASCBKkwggSlAgEAAoIBAQDJUGqaRB11KjxQ\nKHDeG"
                + "........................................................"
                + "Ldt0hAPNl4QKYWCfJm\nNf7Afqaa/RZq0+y/36v83NGENQ==\n" 
                + "-----END PRIVATE KEY-----\n";
        
        String base64Signature = signSHA256RSA(input,strPk);
        System.out.println("Signature="+base64Signature);
    }

    // Create base64 encoded signature using SHA256/RSA.
    private static String signSHA256RSA(String input, String strPk) throws Exception {
        // Remove markers and new line characters in private key
        String realPK = strPk.replaceAll("-----END PRIVATE KEY-----", "")
                             .replaceAll("-----BEGIN PRIVATE KEY-----", "")
                             .replaceAll("\n", "");

        byte[] b1 = Base64.getDecoder().decode(realPK);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(b1);
        KeyFactory kf = KeyFactory.getInstance("RSA");

        Signature privateSignature = Signature.getInstance("SHA256withRSA");
        privateSignature.initSign(kf.generatePrivate(spec));
        privateSignature.update(input.getBytes("UTF-8"));
        byte[] s = privateSignature.sign();
        return Base64.getEncoder().encodeToString(s);
    }
}

Note that the signed string is returned in base64 encoded form. Also note that for Base64 class, you need to use Java 8 or above. If you are using lower Java version, get a third party Base64 encoder.

Do you have a programming problem that you are unable to solve? Please send us your problem and we will publish the solution! Please email us.

Leave a Reply