Signing Documents

To send documents for signing, please use the following steps:

  1. Prepare the encrypted PDF document to be sent to the signer gateway
  2. Making a HTTPS post request to send the document
  3. Receiving the signed document back

Step 1 – Preparing the encrypted payload

emSigner uses TLS and Data encryption in transit to protect your documents. To achieve this, the signer gateway uses a combination of a random session key and public key to encrypt both the request and session key

To prepare the payload use the following steps

Create a unique session key for each request


//.NET Code
public static byte[] GetNewSessionKey()
{
    using (Aes myAes = Aes.Create("AES"))
    {
        myAes.KeySize = 256;
        myAes.GenerateKey();
        return myAes.Key;
    }
}
//Java Code
String JCE_PROVIDER = "BC";
public byte[] GenerateSessionKey() throws NoSuchAlgorithmException, NoSuchProviderException
{
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    KeyGenerator kgen = KeyGenerator.getInstance("AES", JCE_PROVIDER);
    kgen.init(256);
    SecretKey key = kgen.generateKey();
    byte[] symmKey = key.getEncoded();
    return symmKey;
}

Encrypt unique session key for each request

Every session key needs to be encrypted with Public Key of emSigner which will be shared as a .CER file. Please contact us if you already did not receive this file

//.NET Code
public static string EncryptWithPublicKey(byte[] stringToEncrypt)
{
    X509Certificate2 certificate;
    certificate = new X509Certificate2(AppDomain.CurrentDomain.BaseDirectory + "\\certificate.cer");
    byte[] cipherbytes = Convert.FromBase64String(Convert.ToBase64String(stringToEncrypt));
    RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certificate.PublicKey.Key;
    byte[] cipher = rsa.Encrypt(cipherbytes, false);
    return Convert.ToBase64String(cipher);
}
//Java Code
public byte[] EncryptUsingPublicKey(byte[] data) throws IOException, GeneralSecurityException, Exception
{
    // encrypt the session key with the public key
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    PublicKey publicKey = null;
    byte[] bytevalue= readBytesFromFile("Give certificate.cer filepath ");
    //String certificatedata = "";
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
    //byte[] bytevalue = Base64.decode(certificatedata);
    InputStream streamvalue = new ByteArrayInputStream(bytevalue);
    java.security.cert.Certificate certificate = certificateFactory.generateCertificate(streamvalue);
    publicKey = certificate.getPublicKey();
    Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
    pkCipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] encSessionKey = pkCipher.doFinal(data);
    // System.out.println("ENC SESSION KEY : "+ encSessionKey.length);
    return encSessionKey;
}

Create JSON Payload

For PDF Files

Parameter Data Type Description
Please use the parameters below to construct the JSON payload for PDF file signing
Filetype* String Filetype=PDF, If file is PDF format.
File* String Compress the file using 7zip (Optional) and pass compressed base 64 string of file that needs to be signed.
If you are compressing the document make sure you send additional parameter i.e. IsCompressed as TRUE, otherwise FALSE.
Compression ratio is high for XML and DATA, whereas for PDF it is only 10% (Varies with size of the document). To know how to compress file, refer the section at the bottom of this page
IsCompressed Boolean Set to "True" if compressed data is sent. Otherwise "False"
ReferenceNumber * String Pass unique random number as reference number for each transaction request. Maximum of 20 characters.
Example: 1213
Note: You can pass timestamp as a reference number to create uniqueness. You are not allowed to pass reference number which has been used for any of the previous transactions.
Name* String Pass the name of the signatory which will be displayed along with the signature.
Authtoken * String Pass valid unique Authtoken generated for your account.
SignatureType* Integer This parameter describes the signature mode to be enabled for completing the request.
Currently, we support the following signature options i.e. dSign, eSign, eSignature, Digital Signatures (tokens), eSign 2.1 and eSign 3.2 and other signing types from third party trust service providers from time to time
Digital Signature: Requires Crypto Token and valid digital signature issued by licensed Certifying Authorities to digitally sign the request.
eSignature: eSignature is not valid in India, but it is widely accepted in other countries.
eSign : eSign (Aadhar based signing) is valid ONLY in India.
Specify below signature type values (comma separated) if you need specific signature options to be enabled in our gateway page.
SignatureType=2, if you need digital signature as a signature option.
SignatureType=3, if you need eSign as a signature option.
SignatureType=4, if you need eSignature as signature option.
SignerID String This is an optional parameter. Value for this parameter can be passed if “eSign” Signature type is selected as one of the signature type values e.g xyz.123
IsCosign Boolean By default, this parameter would contain a FALSE value.
Set this to TRUE, if you want to sign the document multiple times with different signatories.
For security reasons, if you have only one signatory signing the document pass as false and also for the last signatory of your workflow/business flow you need to pass false so that document will not be allowed for further signing.
SelectPage* String Signature placeholder specification on which page the signature has to be added.
Specify
SelectPage=ALL, if you need a signature on all the pages of the document.
SelectPage=FIRST, if you need a signature on the only first page of the document.
SelectPage=LAST, if you need a signature on only last page of the document.
SelectPage=EVEN, if you need a signature on all even pages of the document. For example: If the document consists of 10 pages then second, fourth, sixth, eighth and tenth pages contain a signature.
SelectPage=ODD, if you need a signature on all odd pages of the document. For example: If the document consists of 10 pages then first, third, fifth, seventh and ninth pages contain a signature.
SelectPage=SPECIFY, if you want to specify page numbers. For specifying page level coordinates, you need to pass additional parameter i.e. PageNumber which is explained below.
SelectPage=PAGE LEVEL, if you want to specify page coordinates. For specifying page level coordinates, you need to pass additional parameter i.e. PagelevelCoordinates which is explained below.
PageNumber Integer Pass page numbers separated with a comma, where you wanted to see the signature in the document. For example: 1,2 Note: This is mandatory if SelectPage is SPECIFY.
PagelevelCoordinates String Specify coordinates of page level as PagelevelCoordinates= Pagenumber1,left,top,width,height;Pagenumber2,left,top,width,height
For example: In 10 pages document you wanted the document to be signed on 1st and 6th page with some co-ordinates then specify PagelevelCoordinates = 1,7,10,60,120;6,45,20,60,120
Note: This is mandatory if SelectPage is PagelevelCoordinates.
SignaturePosition* String Signature placeholder specification where the signature has to be placed on a page.
Specify
SignaturePosition =Top-Left, if you need a signature on a top left position of the document.
SignaturePosition =Top-Center, if you need a signature on a top center position of the document.
SignaturePosition =Top-Right, if you need a signature on a top right position of the document.
SignaturePosition =Middle-Left, if you need a signature on a middle left position of the document.
SignaturePosition =Middle-Right, if you need a signature on a middle right position of the document.
SignaturePosition =Middle-Center, if you need a signature on a middle center position of the document.
SignaturePosition =Bottom-Left, if you need a signature on a bottom left position of the document.
SignaturePosition =Bottom-Right, if you need a signature on a bottom right position of the document.
SignaturePosition =Bottom-Center, if you need a signature on a bottom center position of the document.
SignaturePosition =Customize, if you want to specify page coordinates. For specifying customize coordinates, you need to pass additional parameter i.e. CustomizeCoordinates which is explained below.
CustomizeCoordinates String CustomizeCoordinates=left,top,width,height
For example: In 10 pages document you wanted the document to be signed on particular positions then specify CustomizeCoordinates=7,10,60,120
Note: This is mandatory if SignaturePosition is Customize.
PreviewRequired Boolean By default, this will be FALSE.
If you want to show preview to the user when redirected to emSigner signer gateway page.
Pass TRUE if the preview is required before signing the document.
Enableuploadsignature Boolean By default this will be FALSE, if enabled then the user will have the option to upload handwritten signature in emSigner Signer Gateway page and the same will be affixed on the signed PDF document And using this option will invalidate any signed document sent for signing again by another signatory.
Pass TRUE if you want to enable upload signature option in the gateway.
Note: If the user selects signature type as eSignature or combination of that, then at that time any of the parameter i.e. enable eSignature pad/enable draw signature/enable font signature/enable upload signature is mandatory.
For digital signature, it is not mandatory.
Enablefontsignature Boolean By default this will be FALSE, if enabled then the user will have the option to choose or generate some font based signature in emSigner Signer Gateway page and the same will be affixed on the signed PDF document And using this option will invalidate any signed document sent for signing again by another signatory.
Pass TRUE if you want to enable font based signatures to be visible in the gateway.
Note: If the user selects signature type as eSignature or combination of that, then at that time any of the parameter i.e. enable eSignature pad/enable draw signature/enable font signature/enable upload signature is mandatory. For dSign, it is not mandatory.
EnableDrawSignature Boolean By default this will be FALSE, if enabled then the user will have the option to draw signature in emSigner Signer Gateway page and the same will be affixed on the signed PDF document And using this option will invalidate any signed document sent for signing again by another signatory.
Pass TRUE if you want to enable draw signature option in the gateway.
Note: If the user selects signature type as eSignature or combination of that, then at that time any of the parameter i.e. enable eSignature pad/enable draw signature/enable font signature/enable upload signature is mandatory. For dSign, it is not mandatory.
EnableeSignaturePad Boolean By default this will be FALSE, if enabled then the user will have the option to connect to third-party signature pads. Currently, we support Topaz signature pad in emSigner Signer Gateway page and the same will be affixed on the signed PDF document and using this option will invalidate any signed document sent for signing again by another signatory.
Pass TRUE if you want to enable eSignature pad option in the gateway.
Storetodb Boolean By default this value would be FALSE. Pass it as TRUE if you want to save the response data with us. In case of failure you can request us by calling our API's before 48 hours (If Storetodb=TRUE).
EnableViewDocumentLink Boolean By default thisvalue willbe TRUE. Pass FALSE if document view link is not required.
Note: Document link will be displayed only when preview is not enabled. If Preview required is TRUE then set "EnableViewDocumentLink" as FALSE.
SUrl* String Pass success URL, so that after successful signing signer gateway will send a response to that particular URL.
The response handling can then be done by you after redirection to this URL.
Furl* String Pass failure URL, so that when there is a failure, signer gateway will send a response to that particular URL.
The response handling can then be done by you after redirection to this URL.
Curl* String Pass cancel URL, so that when customer cancels the signer gateway process in the middle, signer gateway will send a response to that particular URL. The response handling can then be done by you after redirection to this URL.
For XML/CMS/DATA files
Parameter Data Type Description
Please use the parameters below to construct the JSON payload for PDF file signing
Filetype* String Filetype=XML, if file is XML format.
Filetype=DATA, if file is Text format.
File* String Compress the file using 7zip (Optional) and pass compressed base 64 string of file that needs to be signed.
If you are compressing the document make sure you send additional parameter i.e. IsCompressed as TRUE, otherwise FALSE.
Compression ratio is high for XML and DATA, whereas for PDF it is only 10% (Varies with size of the document). To know how to compress file, refer to this section.
IsCompressed Boolean Set to "True" if compressed data is sent. Otherwise "False"
ReferenceNumber * String Pass unique random number as reference number for each transaction request. Maximum of 20 characters.
Example: 1213
Note: You can pass timestamp as a reference number to create uniqueness. You are not allowed to pass reference number which has been used for any of the previous transactions.
Authtoken * String Pass valid unique Authtoken generated for your account.
SignatureType* Integer This parameter describes the signature mode to be enabled for completing the request.
Currently, we support the following signature options i.e. digital Signature, eSign, eSignature and other signature types from trust service providers
Digital Signature: Requires Crypto Token and valid digital signature issued by licensed Certifying Authorities to digitally sign the request.
eSignature: eSignature is not valid in India, but it is widely accepted in other countries.
eSign : eSign (Aadhar based signing) is valid ONLY in India.
Specify below signature type values (comma separated) if you need specific signature option to be enabled in our gateway page.
SignatureType=2, if you need digital signature as a signature option.
SignatureType=3, if you need eSign as a signature option.
SignatureType=4, if you need eSignature as signature option.
SignerID String This is an optional parameter. Value for this parameter can be passed if “eSign” Signature type is selected as one of the signature type values e.g xyz.123
Storetodb Boolean By default this value would be FALSE. Pass it as TRUE if you want to save the response data with us. In case of failure you can request us by calling our API's before 48 hours (If Storetodb=TRUE).
EnableViewDocumentLink Boolean By default thisvalue willbe TRUE. Pass FALSE if document view link is not required. Note: Document link will be displayed only when preview is not enabled. If Preview required is TRUE then set "EnableViewDocumentLink" as FALSE.
SUrl* String Pass success URL, so that after successful signing signer gateway will send a response to that particular URL. The response handling can then be done by you after redirection to this URL.
Furl* String Pass failure URL, so that when there is a failure, signer gateway will send a response to that particular URL. The response handling can then be done by you after redirection to this URL.
Curl* String Pass cancel URL, so that when customer cancels the signer gateway process in the middle, signer gateway will send a response to that particular URL. The response handling can then be done by you after redirection to this URL.
For Hash files
Parameter Data Type Description
Please use the parameters below to construct the JSON payload for PDF file signing
Filetype* String Filetype=Hash, if file is an array of hashes.
Documentdetails JSON Array Pass Documentdetails in JSON array format with below details
DocumentName: Name of document that needs to be signed.
DocumentURL: URL of the document. Should be a HTTP / HTTPS URL for the document, accessible by the signer during the transaction permitted duration (maxUserWait Time).
DocumentHash: Sha256 Hash of the document to be signed.
Sample Documentdetails Json:
[
{ "DocumentName": "Document1", "DocumentURL": "https://www.xyz.com/document1", "DocumentHash": "96cac442e493b6e8dd97e2a28dc60d43ed6ff7c6e6d3a0e0490cfcb700046a4b" },
{ "DocumentName": "Document2", "DocumentURL": "https://www.xyz.com/document2", "DocumentHash": "96cac442e493b6e8dd97e2a28dc60d43ed6ff7c6e6d3a0e0490cfcb700046a4a" }]
Note: This array should contain max 5 document.
IsCompressed Boolean Set to "True" if compressed data is sent. Otherwise "False"
ReferenceNumber * String Pass unique random number as reference number for each transaction request. Maximum of 20 characters.
Example: 1213
Note: You can pass timestamp as a reference number to create uniqueness. You are not allowed to pass reference number which has been used for any of the previous transactions.
Authtoken * String Pass valid unique Authtoken generated for your account.
SignatureType* Integer This parameter describes the signature mode to be enabled for completing the request.
Currently, we support the following signature options i.e. digital Signature, eSign, eSignature and other signature types from trust service providers
Digital Signature: Requires Crypto Token and valid digital signature issued by licensed Certifying Authorities to digitally sign the request.
eSignature: eSignature is not valid in India, but it is widely accepted in other countries.
eSign : eSign (Aadhar based signing) is valid ONLY in India.
Specify below signature type values (comma separated) if you need specific signature option to be enabled in our gateway page.
SignatureType=2, if you need digital signature as a signature option.
SignatureType=3, if you need eSign as a signature option.
SignatureType=4, if you need eSignature as signature option.
SignerID String This is an optional parameter. Value for this parameter can be passed if “eSign” Signature type is selected as one of the signature type values e.g xyz.123
Storetodb Boolean By default this value would be FALSE. Pass it as TRUE if you want to save the response data with us. In case of failure you can request us by calling our API's before 48 hours (If Storetodb=TRUE).
EnableViewDocumentLink Boolean By default thisvalue willbe TRUE. Pass FALSE if document view link is not required. Note: Document link will be displayed only when preview is not enabled. If Preview required is TRUE then set "EnableViewDocumentLink" as FALSE.
SUrl* String Pass success URL, so that after successful signing signer gateway will send a response to that particular URL. The response handling can then be done by you after redirection to this URL.
Furl* String Pass failure URL, so that when there is a failure, signer gateway will send a response to that particular URL. The response handling can then be done by you after redirection to this URL.
Curl* String Pass cancel URL, so that when customer cancels the signer gateway process in the middle, signer gateway will send a response to that particular URL. The response handling can then be done by you after redirection to this URL.
Sample JSON Request
{
    "Name":"",
    "FileType":"PDF",
    "SignatureType":2,
    "SelectPage":"FIRST",
    "SignaturePosition":"Top-Left",
    "AuthToken":"",
    "File":"",
    "PageNumber":null,
    "PreviewRequired":true,
    "PagelevelCoordinates":null,
    "CustomizeCoordinates":null,
    "SUrl":"http://localhost:52322/Success",
    "FUrl":"http://localhost:52322/Error",
    "CUrl":"http://localhost:52322/Cancel",
    "ReferenceNumber":"REFDB100011",
    "Enableuploadsignature":true,
    "Enablefontsignature":true,
    "EnableDrawSignature":true,
    "EnableeSignaturePad":true,
    "IsCompressed":true,
    "IsCosign":true,
    "EnableViewDocumentLink ": true,
    "Storetodb":true,
    "IsGSTN":true,
    "IsGSTN3B":false
}
Encrypt JSON Payload

The JSON Payload needs to be encrypted with the Session Key that was generated as part of the first step

//.NET Code
public static byte[] EncryptDataAES(byte[] toEncrypt, byte[] key)
{
    IBufferedCipher cipher = CipherUtilities.GetCipher("AES/ECB/PKCS7");
    cipher.Init(true, new KeyParameter(key));
    int outputSize = cipher.GetOutputSize(toEncrypt.Length);
    byte[] tempOP = new byte[outputSize];
    int processLen = cipher.ProcessBytes(toEncrypt, 0, toEncrypt.Length, tempOP, 0);
    int outputLen = cipher.DoFinal(tempOP, processLen);
    byte[] result = new byte[processLen + outputLen];
    System.Array.Copy(tempOP, 0, result, 0, result.Length);
    return result;
}
//Java Code
public byte[] EncryptUsingSessionKey(byte[] skey, byte[] data) throws InvalidCipherTextException
{
    PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new AESEngine(), new PKCS7Padding());
    cipher.init(true, new KeyParameter(skey));
    //
    int outputSize = cipher.getOutputSize(data.length);
    byte[] tempOP = new byte[outputSize];
    int processLen = cipher.processBytes(data, 0, data.length, tempOP, 0);
    int outputLen = cipher.doFinal(tempOP, processLen);
    byte[] result = new byte[processLen + outputLen];
    System.arraycopy(tempOP, 0, result, 0, result.length);
    return result;
}
Create Hash
//.NET Code
public static byte[] Generatehash256(string text)
{
    byte[] message = Encoding.UTF8.GetBytes(text);
    SHA256Managed hashString = new SHA256Managed();
    string hex = "";
    var hashValue = hashString.ComputeHash(message);
    return hashValue;
}
//Java Code
public static byte[] Generatehash256(string text)
{
    byte[] message = Encoding.UTF8.GetBytes(text);
    SHA256Managed hashString = new SHA256Managed();
    string hex = "";
    var hashValue = hashString.ComputeHash(message);
    return hashValue;
}
Encrypt Hash

Follow the steps used to Encrypt JSON payload to encrypt Hash of Document using the Session Key

This is used as an added security measure to ensure document has not been tampered in transit

Step 2 – Making an HTTPS post to send the document

Once you have completed Step 1, please send the payload to the URL using the format below

TEST URL – “https://testgateway.emsigner.com/eMsecure/V3_0/Index”

Type – HTTPS POST

Request Parameters

Parameter Data Type Description
Parameter 1 * String Encrypted Session Key
Parameter 2 * String Encrypted JSON Data
Parameter 3 String Encrypted Hash
  1. Once Signer Gateway receives the request, it authenticates by decrypting the all the values and compares them to check if there is any man in the middle attack and authorizes the request.
  2. On successful authentication, it redirects the user to the gateway page where the user can view the data based on the request type.
  3. On successful user authentication, signer gateway generates signed data/document with signed data and sends HTTPS POST response to the corporate success URL with Encrypted Signed data, Transaction status, Transaction number and reference number.
  4. Here signed document is compressed using 7-zip (if the file is of larger size) and sent as a response. Signed data will be encrypted using AES encryption with session key received as part of the request.
  5. If authentication fails, user will be redirected to the failure URL and error message will be displayed.

Below is a list of response parameters

Parameter Data Type Description
ReturnStatus String Returns Success if request is done successfully otherwise Failure
ErrorMessage String If ReturnStatus is "Failure" it will return an error message. If this is empty then request is a success. Check below error messages.
Returnvalue String Returns Encrypted Signed data, if signing is done successfully otherwise Failure
Transactionnumber String Returns unique transaction number for each request. To identify each new transaction in the ESGS Database, a unique identifier is created every time. This identifier is known as the Transaction number.
Referencenumber String Returns same reference number which has raised the request.
Error Code Error Message Description
104 Invalid Authtoken When invalid Authtoken is entered
105 You are not subscribed to this VAS item. When No VAS feature is subscribed.
106 Cancelled by user When client cancels the request
107 Invalid parameters When any parameter is empty
108 You cannot use reference number which is already used in previous transactions. When reference number is already used in previous transactions.
109 Invalid Request When decryption of data failed
110 emSigner application is required to digitally sign the documents using token based signature. When emSigner utility is not installed
111 emSigner application is required to digitally sign the documents using token based signature. When utility not running in the system
112 emSigner application is required to digitally sign the documents using token based signature. When port number is mismatch
113 Please update the emSigner utility for new updates If Utility used is not the latest version.
114 eSignature is not applicable for XML and Data signing. When trying to do eSignature for XML and Data files.
115 Only .jpg, .jpeg and .png files can be set as Signature Image. While uploading signature image other than jpg, jpeg and png files Allowed file types are .jpg, .jpeg and .png
116 You can upload maximum of 200KB and minimum of 100KB file size. While uploading big size file Ensure that the size of file should be between (100KB - 200KB)
117 Please connect the eSignature pad to sign and capture the signature image When eSignature Pad is not connected

Compressing Documents (for large files)
//.NET Code
public string CompressFileLZMA(string InputFileName)
{
    string TransactionID = DateTime.Now.ToString("yyyyMMddHHmmssfff");
    string OutputFileName = System.Web.Configuration.WebConfigurationManager.AppSettings["filepath"] + TransactionID + "_" + Path.GetFileName(InputFileName.Split('.')[0]).ToString();
    Int32 dictionary = 1 << 23;
    Int32 posStateBits = 2;
    Int32 litContextBits = 3; // for normal files
    // UInt32 litContextBits = 0; // for 32-bit data
    Int32 litPosBits = 0;
    // UInt32 litPosBits = 2; // for 32-bit data
    Int32 algorithm = 2;
    Int32 numFastBytes = 128;
    string mf = "bt4";
    bool eos = true;
    bool stdInMode = false;
    SevenZip.Sdk.CoderPropId[] propIDs =  {
        SevenZip.Sdk.CoderPropId.DictionarySize,
        SevenZip.Sdk.CoderPropId.PosStateBits,
        SevenZip.Sdk.CoderPropId.LitContextBits,
        SevenZip.Sdk.CoderPropId.LitPosBits,
        SevenZip.Sdk.CoderPropId.Algorithm,
        SevenZip.Sdk.CoderPropId.NumFastBytes,
        SevenZip.Sdk.CoderPropId.MatchFinder,
        SevenZip.Sdk.CoderPropId.EndMarker
    };
    object[] properties = {
    (Int32)(dictionary),
    (Int32)(posStateBits),
    (Int32)(litContextBits),
    (Int32)(litPosBits),
    (Int32)(algorithm),
    (Int32)(numFastBytes),
    mf, eos
    };
    using (FileStream inStream = new FileStream(InputFileName, FileMode.Open))
    {
        using (FileStream outStream = new FileStream(OutputFileName, FileMode.Create))
            {
                SevenZip.Sdk.Compression.Lzma.Encoder encoder = new SevenZip.Sdk.Compression.Lzma.Encoder();
                encoder.SetCoderProperties(propIDs, properties);
                encoder.WriteCoderProperties(outStream);
                    Int64 fileSize;
                    if (eos || stdInMode)
                        fileSize = -1;
                            else
                            fileSize = inStream.Length;
                                for (int i = 0; i < 8; i++)
                                    outStream.WriteByte((Byte)(fileSize >> (8 * i)));
                                    encoder.Code(inStream, outStream, -1, -1, null);
            }
    }
    return OutputFileName;
 }