Sample Code in Java

Authentication sample code for Version 1.04

                                
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import sun.misc.BASE64Decoder;
public class EinvoiceAuth {
    static String folderPath = "";
    static byte[] appKey = null;
    static String userName = "<User Id>";
    static String password = "<Password>";
    static String gstin = "<GSTIN>";
    static String encPayload = "";
    static String authtoken = "";
    static String sek = "";
    static ObjectMapper objectMapper;
    public static void main(String[] args) {
        authtoken = "";
        folderPath = getPath();
        objectMapper = new ObjectMapper();
        try {
            String appKey = Base64.getEncoder().encodeToString(createAESKey());
            String payload = "{\"username\":\"" + userName + "\",\"password\":\"" + password + "\",\"appkey\":\"" + appKey + "\",\"ForceRefreshAccessToken\": true}";
            System.out.println("Payload: Plain: " + payload);
            payload = Base64.getEncoder().encodeToString(payload.getBytes());
            payload = "{\"Data\":\"" + encryptAsymmentricKey(payload) + "\"}";
            System.out.println("Payload: Encrypted: " + payload);
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost postRequest = new HttpPost("<URL>/v1.04/auth");
            postRequest.setHeader("client-id", "<Client Id>");
            postRequest.setHeader("client-secret", "Client Secret");
            postRequest.setHeader("gstin", "GSTIN");
            postRequest.addHeader("KeepAlive", "true");
            postRequest.addHeader("AllowAutoRedirect", "false");
            StringEntity input = new StringEntity(payload);
            input.setContentType("application/json");
            postRequest.setEntity(input);
            HttpResponse response = httpClient.execute(postRequest);
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new RuntimeException("Failed : HTTP error code : " + response.getStatusLine().getStatusCode());
            }
            BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));
            String output;
            String responseText = "";
            while ((output = br.readLine()) != null) {
                responseText = output;
            }
            System.out.println("Response:" + responseText);
            String status = objectMapper.readTree(responseText).get("Status").asText();
            if (status.equals("0")) {
                String errorDesc = "";
                errorDesc = objectMapper.readTree(responseText).get("error").asText();
                //errorDesc = new String(Base64.getDecoder().decode(errorDesc), "utf-8");
                System.out.println("Error: " + errorDesc);
            }
            if (status.equals("1")) {
                authtoken = objectMapper.readTree(responseText).get("Data").get("AuthToken").asText();
                sek = objectMapper.readTree(responseText).get("Data").get("Sek").asText();
                System.out.println("Authtoken: " + authtoken);
                System.out.println("Encrypted SEK: " + sek);
                sek = decrptBySymmetricKeySEK(sek);
                System.out.println("Decrypted SEK: " + sek);
            }
            httpClient.getConnectionManager().shutdown();
        } catch (Exception ex) {
            Logger.getLogger(EWayBillAuth.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public static PublicKey getPublicKey() throws FileNotFoundException, IOException, NoSuchAlgorithmException, InvalidKeySpecException {
        FileInputStream in = new FileInputStream("<Path to File>/einv_sandbox.pem");
        byte[] keyBytes = new byte[in.available()];
        in.read(keyBytes);
        in.close();
        String pubKey = new String(keyBytes, "UTF-8");
        pubKey = pubKey.replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", "");
        BASE64Decoder decoder = new BASE64Decoder();
        keyBytes = decoder.decodeBuffer(pubKey);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(spec);
        return publicKey;
    }
    public static byte[] createAESKey() {
        try {
            KeyGenerator gen = KeyGenerator.getInstance("AES");
            gen.init(128);
            /* 128-bit AES */
            SecretKey secret = gen.generateKey();
            appKey = secret.getEncoded();
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(EWayBillAuth.class.getName()).log(Level.SEVERE, null, ex);
        }
        return appKey;
    }
    private static String encryptAsymmentricKey(String clearText) throws Exception {
        PublicKey publicKeys = getPublicKey();
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, publicKeys);
        byte[] encryptedText = cipher.doFinal(clearText.getBytes());
        String encryptedPassword = Base64.getEncoder().encodeToString(encryptedText);
        return encryptedPassword;
    }
    public static String getPath() {
        String folderPath = "";
        try {
            File tempFile = new File(EWayBillAuth.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
            folderPath = tempFile.getParentFile().getPath() + "\\";
            return folderPath;
        } catch (URISyntaxException ex) {
            Logger.getLogger(EWayBillAuth.class.getName()).log(Level.SEVERE, null, ex);
        }
        return folderPath;
    }
    public static String decrptBySymmetricKeySEK(String encryptedSek) {
        Key aesKey = new SecretKeySpec(appKey, "AES"); // converts bytes(32 byte random generated) to key
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");  // encryption type = AES with padding PKCS5
            cipher.init(Cipher.DECRYPT_MODE, aesKey); // initiate decryption type with the key
            byte[] encryptedSekBytes = Base64.getDecoder().decode(encryptedSek); // decode the base64 encryptedSek to bytes
            byte[] decryptedSekBytes = cipher.doFinal(encryptedSekBytes); // decrypt the encryptedSek with the initialized cipher containing the key(Results in bytes)
            byte[] sekBytes = decryptedSekBytes;
            String decryptedSek = Base64.getEncoder().encodeToString(decryptedSekBytes); // convert the decryptedSek(bytes) to Base64 String
            return decryptedSek;  // return results in base64 string
        } catch (Exception e) {
            return "Exception; " + e;
        }
    }
}


Symmetric Key Encryption using Java.

private static String encryptBySymmetricKey(String json, String decryptedSek)
  {
   byte[] sekByte = Base64.decodeBase64(decryptedSek);
    Key aesKey = new SecretKeySpec(sekByte, "AES");
   try {

    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, aesKey);
     byte[] encryptedjsonbytes = cipher.doFinal(json.getBytes());
    String encryptedJson = Base64.encodeBase64String(encryptedjsonbytes);
    return encryptedJson;
 }
  catch(Exception e) {
  return "Exception "+e;
   }
}


Symmetric Key Decryption using Java (Decrypt using SEK)

  public static String decryptBySymmentricKey(String data, String decryptedSek) {
     byte[] sekByte = Base64.getDecoder().decode(decryptedSek);
     Key aesKey = new SecretKeySpec(sekByte, "AES");
      try {
           Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
           cipher.init(Cipher.DECRYPT_MODE, aesKey);
           byte[] decordedValue = new BASE64Decoder().decodeBuffer(data);
           byte[] decValue = cipher.doFinal(decordedValue);
           return new String(decValue);
       } catch (Exception e) {
           return "Exception " + e;
        }
    }

Decoding the Signed eInvoice

 private void decodeSignedJWT(String signedText)
 {
   try {
     BASE64Decoder decoder = new BASE64Decoder();
     String[]  splitSignedText = signedText.split("\\.");
     String decodedSigned =new String(decoder.decodeBuffer(splitSignedText[0]));
     decodedSigned = decodedSigned +"\n Content:"+(new String(decoder.decodeBuffer(splitSignedText[1])));
     decodedSigned.replaceAll("\\\"", "\"");
     System.out.println("\nDecoded Text:" + decodedSigned);
   } catch (IOException ex) {
     Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
    }
  }