---
page_source: https://juspay.io/in/docs/upi-plugin-sdk/cordova/resources/generating-the-signature
page_title: Generating the Signature
---


# Generating the Signature




---



## **Generating the RSA Key Pair** 



Merchant must securely generate 2048 bit RSA Public Private Key pair on their servers inside a crypto vault. Merchant must share the Public Key (KeyFormat-PEM) with Juspay during onboarding.Private key must be securely kept in a crypto vault on the merchant servers. Private key should never flow to the client.

> **Note**
> To simplify integration on sandbox, we have already shared a set of auto-generated keys which need to be configured. Please make sure a new set of keys is generated for production prior to go-live.



The below command would generate a private key file **private-key.pem** 


#### Command Line Code Snippet:

```command line
$ openssl genrsa -out private-key.pem 2048
```


The below command would generate a public key file **public-key.pem**  for the private key file generated via above command


#### Command Line Code Snippet:

```command line
$ openssl rsa -in private-key.pem -pubout -out public-key.pem
```



## **Signing the Payload** 




| Algorithm | Format |
|---|---|
| RSA-SHA256 | HEX; base 64 encoded |


JSON payload needs to be signed after converting it to String using the Private key stored on the merchant server. The signature shall be in **Base 64 encoded format.** 

> **Warning**
> The JSON payload converted to a string that is to be signed, which makes a signature, should exactly be the same as the string that is to be passed in the signature payload field.




### **Sample Code Snippet** 




#### Java Code Snippet:

```java
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.json.JSONObject;

import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.HashMap;

import javax.xml.bind.DatatypeConverter;

public class SignatureUtil {
    public static void main(String ...args) {
        JSONObject data = new JSONObject("{'order_id': 'venkatesh12','first_name': 'Test','last_name': 'Customer','customer_phone': '9876543210','customer_email': 'test@gmail.com','merchant_id': 'udit_juspay','amount': '1.00','customer_id': '9876543210','return_url': 'https://sandbox.juspay.in/end','currency': 'INR','mandate.start_date': '1638535683287','mandate.end_date': '2134731745451','timestamp': '1576227696'}");
        String filePath = "/<absolute-path-to-folder-containing-pem-file>/private-key.pem";
        HashMap<String,String> response = createSignature(data, filePath);
    }

    public static HashMap<String,String> createSignature(JSONObject payload, String filePath) {
        try {
            PrivateKey privateKey = readPrivateKeyFromFile(filePath);
            Signature privateSignature = Signature.getInstance("SHA256withRSA");
            String[] requiredFields = {"order_id", "merchant_id", "amount", "timestamp", "customer_id"};
            for (String key : requiredFields)
                if(!payload.has(key))
                    throw new Exception(key + " not found in payload");
            String signaturePayload = payload.toString();
            privateSignature.initSign(privateKey);
            privateSignature.update(signaturePayload.getBytes(StandardCharsets.UTF_8));
            byte[] signature = privateSignature.sign();
            String encodedSignature = DatatypeConverter.printBase64Binary(signature);
            HashMap<String,String> response = new HashMap<String,String>();
            response.put("signature",encodedSignature);
            response.put("signaturePayload", signaturePayload);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new HashMap<String, String>();
    }

    private static PrivateKey readPrivateKeyFromFile(String filePath) throws IOException {
        Security.addProvider(new BouncyCastleProvider());
        PEMParser pemParser = new PEMParser(new FileReader(filePath));
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        PEMKeyPair pemKeyPair = (PEMKeyPair) pemParser.readObject();
        KeyPair keyPair = converter.getKeyPair(pemKeyPair);
        return keyPair.getPrivate();
    }
}
```

#### Alternate Java (below JDK 11) Code Snippet:

```alternate java (below jdk 11)
import sun.security.util.DerInputStream;
import sun.security.util.DerValue;
import javax.xml.bind.DatatypeConverter;
import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.util.HashMap;

import org.json.JSONObject;

public class SignatureUtil {

    //The method that signs the data using the private key that is stored in keyFile path
    public static HashMap<String, String> createSignature (JSONObject payload, String keyContentOrFile) throws Exception {
        Signature rsa = Signature.getInstance("SHA256withRSA");
        PrivateKey privateKey = null;

        if (keyContentOrFile.startsWith("--")) {
            privateKey = readPrivateKey(keyContentOrFile);
        } else {
            privateKey = readPrivateKeyFromFile(keyContentOrFile);
        }
        String[] requiredFields = {"order_id", "merchant_id", "amount", "timestamp", "customer_id"};
        for (String key : requiredFields)
            if(!payload.has(key))
                throw new Exception(key + " not found in payload");
        String signaturePayload = payload.toString();
        rsa.initSign(privateKey);
        rsa.update(signaturePayload.getBytes());
        byte[] sign =  rsa.sign();
        String encodedSignature = DatatypeConverter.printBase64Binary(sign);
        HashMap<String,String> response = new HashMap<String,String>();
        response.put("signature",encodedSignature);
        response.put("signaturePayload", signaturePayload);
        return response;
    }

    //Method to retrieve the Private Key from a file
    public static PrivateKey readPrivateKeyFromFile(String filename) throws Exception {
        File keyFile = new File(filename);
        BufferedReader reader = new BufferedReader(new FileReader(keyFile));
        String line;
        StringBuffer fileContent = new StringBuffer();
        Boolean isPkcs1Content = false;
        while ((line = reader.readLine()) != null) {
            if (!line.startsWith("--")) {
                fileContent.append(line).append("\n");
            } else if (!isPkcs1Content && line.startsWith("-----BEGIN RSA PRIVATE KEY-----")){
                isPkcs1Content = true;
            }
        }
        byte[] keyBytes = DatatypeConverter.parseBase64Binary(fileContent.toString());
        return generatePrivateKey(keyBytes, isPkcs1Content);
    }

    //Method to retrieve the Private Key from a variable
    public static PrivateKey readPrivateKey(String content) throws Exception {
        Boolean isPkcs1Content = false;

        if (content.startsWith("-----BEGIN RSA PRIVATE KEY-----")){
            isPkcs1Content = true;
        }
        content = content.replaceAll("-----BEGIN RSA PRIVATE KEY-----","");
        content = content.replaceAll("-----BEGIN PRIVATE KEY-----","");
        content = content.replaceAll("-----END RSA PRIVATE KEY-----","");
        content = content.replaceAll("-----END PRIVATE KEY-----","");
        byte[] keyBytes = DatatypeConverter.parseBase64Binary(content);
        return generatePrivateKey(keyBytes, isPkcs1Content);
    }

    private static PrivateKey generatePrivateKey(byte[] keyBytes, Boolean isPkcs1Content) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
        PrivateKey privateKey = null;
        if (isPkcs1Content) {
            DerInputStream derReader = new DerInputStream(keyBytes);
            DerValue[] seq = derReader.getSequence(0);
            // skip version seq[0];
            BigInteger modulus = seq[1].getBigInteger();
            BigInteger publicExp = seq[2].getBigInteger();
            BigInteger privateExp = seq[3].getBigInteger();
            BigInteger prime1 = seq[4].getBigInteger();
            BigInteger prime2 = seq[5].getBigInteger();
            BigInteger exp1 = seq[6].getBigInteger();
            BigInteger exp2 = seq[7].getBigInteger();
            BigInteger crtCoef = seq[8].getBigInteger();

            RSAPrivateCrtKeySpec keySpec =
                    new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            privateKey = keyFactory.generatePrivate(keySpec);
        } else {
            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory kf = KeyFactory.getInstance("RSA");
            privateKey = kf.generatePrivate(spec);
        }
        return privateKey;
    }

    public static void main(String[] args) throws Exception{
        JSONObject data = new JSONObject("{'order_id': 'venkatesh12','first_name': 'Test','last_name': 'Customer','customer_phone': '9876543210','customer_email': 'test@gmail.com','merchant_id': 'udit_juspay','amount': '1.00','customer_id': '9876543210','return_url': 'https://sandbox.juspay.in/end','currency': 'INR','mandate.start_date': '1638535683287','mandate.end_date': '2134731745451','timestamp': '312342'}");
        
        //This is a sample snippet. Always store and fetch the private key from crypto vault
        String fileContent = "-----BEGIN RSA PRIVATE KEY-----\r\n" +
                "MIIEpAIBAAKCAQEAzEHPYKNYRcZoWtgTvYPEmTeiSlMxJwNPf8bRJ5U6cXiup2j/\r\n" +
                "a/l1oAiuVNQiDRzvSflS80FoRjQjcGRyqTYcYYYUTYOTh6j1WY1SQuPqrsvGNR3L\r\n" +
                "/6CfbI2iD4bPRx2XdPbxr6UoHNvh6y1hAscZy5oxSCT6WW5jCpW1Bg==\r\n" +
                "-----END RSA PRIVATE KEY-----\r\n";

        // Sign with content in code
        HashMap<String,String> p1 = createSignature(data, fileContent);

        // Sign with content in file on given absolute path
        HashMap<String,String> p2 = createSignature(data, "/<absolute-path-to-folder-containing-pem-file>/private-key.pem");
    
    }
}
```

#### Python Code Snippet:

```python
#!/bin/python
# pip install pycryptodome 

import json

from Crypto.PublicKey import RSA # ignore this
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from base64 import b64encode

privateKeyString = "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAA70vuNEyFLz2FzpPYzwN5...aX1rYhPBmS89Yt6pu6McT7jlnw\n-----END RSA PRIVATE KEY-----"
# This is a sample snippet. Always store and fetch the private key from crypto vault

privateKey = RSA.import_key(privateKeyString)

def createSignature (payload, privateKey):
    requiredFields = ["order_id", "merchant_id", "amount", "timestamp", "customer_id"]
    signaturePayload = json.dumps(payload)
    for key in requiredFields:
        if key not in payload:
            raise ValueError (key , " not found in payload")
    signer = PKCS1_v1_5.new(privateKey)
    digest = SHA256.new()
    digest.update(signaturePayload.encode('utf-8'))
    signature = signer.sign(digest)
    encodedSignature = b64encode(signature)
    return encodedSignature, signaturePayload
```

#### PHP Code Snippet:

```php
<?php
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAA70vuNEyFLz2FzpPYzwN5aX1rYhPBmS89Yt6pu6McT7jlnw\n-----END RSA PRIVATE KEY-----";

// This is a sample snippet. Always store and fetch the private key from crypto vault

function createSignature($payload, $privateKey) {
    $response = array();
    $requiredFields = ["order_id", "merchant_id", "amount", "timestamp", "customer_id"];
    foreach ($requiredFields as $key){
        if(!array_key_exists($key, $payload)){
            echo $key . " is not present ";
            return;
        }
    }
    $signaturePayload = json_encode($payload);
    $signature = "";
    openssl_sign($signaturePayload, $signature, $privateKey, "sha256WithRSAEncryption");
    array_push($response, base64_encode($signature));
    array_push($response,$signaturePayload);
    return $response;
}
?>
```

#### Node.js Code Snippet:

```node.js
const privateKeyString = "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAA70vuNEyFLz2FzpPYzwN5aX1rYhPBmS89Yt6pu6McT7jlnw\n-----END RSA PRIVATE KEY-----"    
 
// This is a sample snippet. Always store and fetch the private key from crypto vault

privateKey = new NodeRSA(privateKeyString);

function createSignature (payload, privateKey) {
    const requiredFields = ["order_id", "merchant_id", "amount", "timestamp", "customer_id"];
    var objKeys = Object.keys(payload);

    if (requiredFields.every(key => objKeys.includes(key))){
        const signaturePayload = JSON.stringify(payload);
        const signature = privateKey.sign(signaturePayload, "base64", "utf8");
        return {signature, signaturePayload}
    }
    throw Error ("Not a valid JSON payload");
}
```

#### C# Code Snippet:

```c#
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.OpenSsl;
using Newtonsoft.Json.Linq;

class SignatureUtil {
    // string filePath = "/<absolute-path-to-folder-containing-pem-file>/private-key.pem";
    public static Dictionary<string,string> createSignature (JObject payload, string filePath){
        string[] requiredFields = {"order_id", "merchant_id", "amount", "timestamp", "customer_id"};
        foreach (string key in requiredFields)
            if(!payload.ContainsKey(key))
                throw new Exception (key + " not found in payload");
        string signaturePayload = payload.ToString();
        byte[] byteArrayPayload = ASCIIEncoding.ASCII.GetBytes(signaturePayload);
        StreamReader sr = new StreamReader(filePath);
        PemReader pr = new PemReader(sr);
        AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
        RsaKeyParameters privateKey = (RsaKeyParameters) keyPair.Private;
        ISigner sign = SignerUtilities.GetSigner(PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id);
        sign.Init(true, privateKey);
        sign.BlockUpdate(byteArrayPayload, 0, byteArrayPayload.Length);
        byte[] signature = sign.GenerateSignature();
        string encodeSignature = Convert.ToBase64String(signature);
        Dictionary<string, string> response = new Dictionary<string, string>();
        response.Add("signature", encodeSignature);
        response.Add("signaturePayload", signaturePayload);
        Console.Write(encodeSignature);
        return response;
    }
}
```

#### Ruby Code Snippet:

```ruby
require 'openssl'
require 'base64'
require 'json'

privateKeyString = "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAA70vuN....EyFLz2FzpPYzwN5aX1rYhPBmS89Yt6pu6McT7jlnw\n-----END RSA PRIVATE KEY-----"
privateKey = OpenSSL::PKey::RSA.new(privateKeyString)
# This is a sample snippet. Always store and fetch the private key from crypto vault

def createSignature (payload, privateKey)
    requiredFields = ["order_id", "merchant_id", "amount", "timestamp", "customer_id"]
    signaturePayload = JSON.generate(payload)
    jsonPayload = JSON.parse(signaturePayload)
    for key in requiredFields do
        if !jsonPayload.has_key?(key)
            raise (key + " not found in payload \n")
        end
    end
    signature = privateKey.sign(OpenSSL::Digest::SHA256.new, signaturePayload)
    encodedSignature = Base64.encode64(signature).delete!("\n")
    return encodedSignature, signaturePayload
end
```


