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);
}
}