{"id":1775,"date":"2023-05-24T09:22:05","date_gmt":"2023-05-24T09:22:05","guid":{"rendered":"https:\/\/whitebooks.in\/blog\/?p=1775"},"modified":"2023-05-24T09:22:07","modified_gmt":"2023-05-24T09:22:07","slug":"java-code-samples-for-generating-e-invoices-through-apis","status":"publish","type":"post","link":"https:\/\/whitebooks.in\/blog\/java-code-samples-for-generating-e-invoices-through-apis\/","title":{"rendered":"Java code samples for generating E-Invoices through APIs"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">Authentication sample code for Version 1.04<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>import com.fasterxml.jackson.databind.ObjectMapper;\r\nimport java.io.BufferedReader;\r\nimport java.io.File;\r\nimport java.io.FileInputStream;\r\nimport java.io.FileNotFoundException;\r\nimport java.io.IOException;\r\nimport java.io.InputStreamReader;\r\nimport java.net.URISyntaxException;\r\nimport java.security.Key;\r\nimport java.security.KeyFactory;\r\nimport java.security.NoSuchAlgorithmException;\r\nimport java.security.PublicKey;\r\nimport java.security.spec.InvalidKeySpecException;\r\nimport java.security.spec.X509EncodedKeySpec;\r\nimport java.util.Base64;\r\nimport java.util.logging.Level;\r\nimport java.util.logging.Logger;\r\nimport javax.crypto.Cipher;\r\nimport javax.crypto.KeyGenerator;\r\nimport javax.crypto.SecretKey;\r\nimport javax.crypto.spec.SecretKeySpec;\r\nimport org.apache.http.HttpResponse;\r\nimport org.apache.http.client.methods.HttpPost;\r\nimport org.apache.http.entity.StringEntity;\r\nimport org.apache.http.impl.client.DefaultHttpClient;\r\nimport sun.misc.BASE64Decoder;\r\npublic class EinvoiceAuth {\r\n    static String folderPath = \"\";\r\n    static byte&#91;] appKey = null;\r\n    static String userName = \"&lt;User Id>\";\r\n    static String password = \"&lt;Password>\";\r\n    static String gstin = \"&lt;GSTIN>\";\r\n    static String encPayload = \"\";\r\n    static String authtoken = \"\";\r\n    static String sek = \"\";\r\n    static ObjectMapper objectMapper;\r\n    public static void main(String&#91;] args) {\r\n        authtoken = \"\";\r\n        folderPath = getPath();\r\n        objectMapper = new ObjectMapper();\r\n        try {\r\n            String appKey = Base64.getEncoder().encodeToString(createAESKey());\r\n            String payload = \"{\\\"username\\\":\\\"\" + userName + \"\\\",\\\"password\\\":\\\"\" + password + \"\\\",\\\"appkey\\\":\\\"\" + appKey + \"\\\",\\\"ForceRefreshAccessToken\\\": true}\";\r\n            System.out.println(\"Payload: Plain: \" + payload);\r\n            payload = Base64.getEncoder().encodeToString(payload.getBytes());\r\n            payload = \"{\\\"Data\\\":\\\"\" + encryptAsymmentricKey(payload) + \"\\\"}\";\r\n            System.out.println(\"Payload: Encrypted: \" + payload);\r\n            DefaultHttpClient httpClient = new DefaultHttpClient();\r\n            HttpPost postRequest = new HttpPost(\"&lt;URL>\/v1.04\/auth\");\r\n            postRequest.setHeader(\"client-id\", \"&lt;Client Id>\");\r\n            postRequest.setHeader(\"client-secret\", \"Client Secret\");\r\n            postRequest.setHeader(\"gstin\", \"GSTIN\");\r\n            postRequest.addHeader(\"KeepAlive\", \"true\");\r\n            postRequest.addHeader(\"AllowAutoRedirect\", \"false\");\r\n            StringEntity input = new StringEntity(payload);\r\n            input.setContentType(\"application\/json\");\r\n            postRequest.setEntity(input);\r\n            HttpResponse response = httpClient.execute(postRequest);\r\n            if (response.getStatusLine().getStatusCode() != 200) {\r\n                throw new RuntimeException(\"Failed : HTTP error code : \" + response.getStatusLine().getStatusCode());\r\n            }\r\n            BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));\r\n            String output;\r\n            String responseText = \"\";\r\n            while ((output = br.readLine()) != null) {\r\n                responseText = output;\r\n            }\r\n            System.out.println(\"Response:\" + responseText);\r\n            String status = objectMapper.readTree(responseText).get(\"Status\").asText();\r\n            if (status.equals(\"0\")) {\r\n                String errorDesc = \"\";\r\n                errorDesc = objectMapper.readTree(responseText).get(\"error\").asText();\r\n                \/\/errorDesc = new String(Base64.getDecoder().decode(errorDesc), \"utf-8\");\r\n                System.out.println(\"Error: \" + errorDesc);\r\n            }\r\n            if (status.equals(\"1\")) {\r\n                authtoken = objectMapper.readTree(responseText).get(\"Data\").get(\"AuthToken\").asText();\r\n                sek = objectMapper.readTree(responseText).get(\"Data\").get(\"Sek\").asText();\r\n                System.out.println(\"Authtoken: \" + authtoken);\r\n                System.out.println(\"Encrypted SEK: \" + sek);\r\n                sek = decrptBySymmetricKeySEK(sek);\r\n                System.out.println(\"Decrypted SEK: \" + sek);\r\n            }\r\n            httpClient.getConnectionManager().shutdown();\r\n        } catch (Exception ex) {\r\n            Logger.getLogger(EWayBillAuth.class.getName()).log(Level.SEVERE, null, ex);\r\n        }\r\n    }\r\n    public static PublicKey getPublicKey() throws FileNotFoundException, IOException, NoSuchAlgorithmException, InvalidKeySpecException {\r\n        FileInputStream in = new FileInputStream(\"&lt;Path to File>\/einv_sandbox.pem\");\r\n        byte&#91;] keyBytes = new byte&#91;in.available()];\r\n        in.read(keyBytes);\r\n        in.close();\r\n        String pubKey = new String(keyBytes, \"UTF-8\");\r\n        pubKey = pubKey.replaceAll(\"(-+BEGIN PUBLIC KEY-+\\\\r?\\\\n|-+END PUBLIC KEY-+\\\\r?\\\\n?)\", \"\");\r\n        BASE64Decoder decoder = new BASE64Decoder();\r\n        keyBytes = decoder.decodeBuffer(pubKey);\r\n        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);\r\n        KeyFactory keyFactory = KeyFactory.getInstance(\"RSA\");\r\n        PublicKey publicKey = keyFactory.generatePublic(spec);\r\n        return publicKey;\r\n    }\r\n    public static byte&#91;] createAESKey() {\r\n        try {\r\n            KeyGenerator gen = KeyGenerator.getInstance(\"AES\");\r\n            gen.init(128);\r\n            \/* 128-bit AES *\/\r\n            SecretKey secret = gen.generateKey();\r\n            appKey = secret.getEncoded();\r\n        } catch (NoSuchAlgorithmException ex) {\r\n            Logger.getLogger(EWayBillAuth.class.getName()).log(Level.SEVERE, null, ex);\r\n        }\r\n        return appKey;\r\n    }\r\n    private static String encryptAsymmentricKey(String clearText) throws Exception {\r\n        PublicKey publicKeys = getPublicKey();\r\n        Cipher cipher = Cipher.getInstance(\"RSA\/ECB\/PKCS1PADDING\");\r\n        cipher.init(Cipher.ENCRYPT_MODE, publicKeys);\r\n        byte&#91;] encryptedText = cipher.doFinal(clearText.getBytes());\r\n        String encryptedPassword = Base64.getEncoder().encodeToString(encryptedText);\r\n        return encryptedPassword;\r\n    }\r\n    public static String getPath() {\r\n        String folderPath = \"\";\r\n        try {\r\n            File tempFile = new File(EWayBillAuth.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());\r\n            folderPath = tempFile.getParentFile().getPath() + \"\\\\\";\r\n            return folderPath;\r\n        } catch (URISyntaxException ex) {\r\n            Logger.getLogger(EWayBillAuth.class.getName()).log(Level.SEVERE, null, ex);\r\n        }\r\n        return folderPath;\r\n    }\r\n    public static String decrptBySymmetricKeySEK(String encryptedSek) {\r\n        Key aesKey = new SecretKeySpec(appKey, \"AES\"); \/\/ converts bytes(32 byte random generated) to key\r\n        try {\r\n            Cipher cipher = Cipher.getInstance(\"AES\/ECB\/PKCS5Padding\");  \/\/ encryption type = AES with padding PKCS5\r\n            cipher.init(Cipher.DECRYPT_MODE, aesKey); \/\/ initiate decryption type with the key\r\n            byte&#91;] encryptedSekBytes = Base64.getDecoder().decode(encryptedSek); \/\/ decode the base64 encryptedSek to bytes\r\n            byte&#91;] decryptedSekBytes = cipher.doFinal(encryptedSekBytes); \/\/ decrypt the encryptedSek with the initialized cipher containing the key(Results in bytes)\r\n            byte&#91;] sekBytes = decryptedSekBytes;\r\n            String decryptedSek = Base64.getEncoder().encodeToString(decryptedSekBytes); \/\/ convert the decryptedSek(bytes) to Base64 String\r\n            return decryptedSek;  \/\/ return results in base64 string\r\n        } catch (Exception e) {\r\n            return \"Exception; \" + e;\r\n        }\r\n    }\r\n}\r<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Symmetric Key Encryption using Java.<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>private static String encryptBySymmetricKey(String json, String decryptedSek)\r\n  {\r\n   byte&#91;] sekByte = Base64.decodeBase64(decryptedSek);\r\n    Key aesKey = new SecretKeySpec(sekByte, \"AES\");\r\n   try {\r\n\r\n    Cipher cipher = Cipher.getInstance(\"AES\/ECB\/PKCS5Padding\");\r\n    cipher.init(Cipher.ENCRYPT_MODE, aesKey);\r\n     byte&#91;] encryptedjsonbytes = cipher.doFinal(json.getBytes());\r\n    String encryptedJson = Base64.encodeBase64String(encryptedjsonbytes);\r\n    return encryptedJson;\r\n }\r\n  catch(Exception e) {\r\n  return \"Exception \"+e;\r\n   }\r\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Symmetric Key Decryption using Java (Decrypt using SEK)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\r  public static String decryptBySymmentricKey(String data, String decryptedSek) {\r\n     byte&#91;] sekByte = Base64.getDecoder().decode(decryptedSek);\r\n     Key aesKey = new SecretKeySpec(sekByte, \"AES\");\r\n      try {\r\n           Cipher cipher = Cipher.getInstance(\"AES\/ECB\/PKCS5Padding\");\r\n           cipher.init(Cipher.DECRYPT_MODE, aesKey);\r\n           byte&#91;] decordedValue = new BASE64Decoder().decodeBuffer(data);\r\n           byte&#91;] decValue = cipher.doFinal(decordedValue);\r\n           return new String(decValue);\r\n       } catch (Exception e) {\r\n           return \"Exception \" + e;\r\n        }\r\n    }<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Decoding the Signed eInvoice<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\r private void decodeSignedJWT(String signedText)\r\n {\r\n   try {\r\n     BASE64Decoder decoder = new BASE64Decoder();\r\n     String&#91;]  splitSignedText = signedText.split(\"\\\\.\");\r\n     String decodedSigned =new String(decoder.decodeBuffer(splitSignedText&#91;0]));\r\n     decodedSigned = decodedSigned +\"\\n Content:\"+(new String(decoder.decodeBuffer(splitSignedText&#91;1])));\r\n     decodedSigned.replaceAll(\"\\\\\\\"\", \"\\\"\");\r\n     System.out.println(\"\\nDecoded Text:\" + decodedSigned);\r\n   } catch (IOException ex) {\r\n     Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);\r\n    }\r\n  }<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Authentication sample code for Version 1.04 Symmetric Key Encryption using Java. Symmetric Key Decryption using Java (Decrypt using SEK) Decoding the Signed eInvoice<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","neve_meta_reading_time":"","_themeisle_gutenberg_block_has_review":false,"footnotes":""},"categories":[95],"tags":[],"class_list":["post-1775","post","type-post","status-publish","format-standard","hentry","category-e-invoicing"],"_links":{"self":[{"href":"https:\/\/whitebooks.in\/blog\/wp-json\/wp\/v2\/posts\/1775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/whitebooks.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/whitebooks.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/whitebooks.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/whitebooks.in\/blog\/wp-json\/wp\/v2\/comments?post=1775"}],"version-history":[{"count":1,"href":"https:\/\/whitebooks.in\/blog\/wp-json\/wp\/v2\/posts\/1775\/revisions"}],"predecessor-version":[{"id":1776,"href":"https:\/\/whitebooks.in\/blog\/wp-json\/wp\/v2\/posts\/1775\/revisions\/1776"}],"wp:attachment":[{"href":"https:\/\/whitebooks.in\/blog\/wp-json\/wp\/v2\/media?parent=1775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/whitebooks.in\/blog\/wp-json\/wp\/v2\/categories?post=1775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/whitebooks.in\/blog\/wp-json\/wp\/v2\/tags?post=1775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}