e-invoice-gst-portal
Version:
This is for e-invoice encrypted and decrypted with SEK key.
118 lines (100 loc) • 3.88 kB
JavaScript
const request = require('request');
const crypto = require('crypto');
const forge = require('node-forge');
const fs = require('fs');
function getSEK(PUBLIC_KEY_PATH_ARG,CLIENT_ID_ARG,CLIENT_SECRET_ARG,USERNAME_ARG,PASSWORD_ARG,GSTIN_ARG,URL_ARG) {
const PUBLIC_KEY_PATH = PUBLIC_KEY_PATH_ARG;
const CLIENT_ID = CLIENT_ID_ARG;
const CLIENT_SECRET = CLIENT_SECRET_ARG;
const USERNAME = USERNAME_ARG;
const PASSWORD = PASSWORD_ARG;
const GSTIN = GSTIN_ARG;
const URL = URL_ARG;
// Read the public key from PEM file
function readPublicKeyFromPem(pemPath) {
const pem = fs.readFileSync(pemPath, 'utf8');
const publicKey = forge.pki.publicKeyFromPem(pem);
return publicKey;
}
// Generate a secure AES key
function generateSecureKey() {
return crypto.randomBytes(32);
}
// Encrypt data using the public key
function encrypt(data, publicKey) {
const encrypted = publicKey.encrypt(data, 'RSAES-PKCS1-V1_5');
return Buffer.from(encrypted, 'binary').toString('base64');
}
// Decrypt data using AES
function decryptBySymmetricKey(encryptedText, key) {
const decipher = crypto.createDecipheriv('aes-256-ecb', key, "");
decipher.setAutoPadding(true);
var decryptedSecret = decipher.update(encryptedText,"base64","base64");
decryptedSecret += decipher.final("base64");
return decryptedSecret;
}
async function callServerApi() {
try {
const publicKey = readPublicKeyFromPem(PUBLIC_KEY_PATH);
const aesKey = generateSecureKey();
const aesKeyBase64 = Buffer.from(aesKey).toString('base64');
const authPayload = {
Password: PASSWORD,
AppKey: aesKeyBase64,
UserName: USERNAME,
ForceRefreshAccessToken: false
};
const authStr = JSON.stringify(authPayload);
const authBytes = Buffer.from(authStr, 'utf8');
const encryptedAuthData = encrypt(authBytes.toString('base64'), publicKey);
const requestPayload = {
Data: encryptedAuthData
};
const headers = {
'client-id': CLIENT_ID,
'client-secret': CLIENT_SECRET,
'gstin': GSTIN,
'Content-Type': 'application/json'
};
request.post({
url: URL,
json: requestPayload,
headers: headers
}, (error, response, body) => {
if (error) {
return {"Status":false,"message":"Error in government."};
} else {
if (body.Status===1){
if (body && body.Data && body.Data.Sek) {
const decryptedData = decryptBySymmetricKey(body.Data.Sek, aesKey);
return {"Status":true,"message":"Sucess.",'Data':{'Sek':decryptedData.toString('utf8'),'AuthToken':body.Data.AuthToken}};
} else {
return {"Status":false,"message":"Error in government website."};
}
}else{
return {"Status":false,"message":"Error in government website."}
}
}
});
} catch (error) {
return {"Status":false,"message":"Error in government website."}
}
}
callServerApi();
}
function encryptBySymmetricKey(jsonData,sek) {
const cipher = crypto.createCipheriv('aes-256-ecb', Buffer.from(sek, 'base64'), '');
cipher.setAutoPadding(true);
var ciph = cipher.update(jsonData,'utf8', 'base64');
ciph += cipher.final('base64');
return ciph;
}
function decryptKey(data, decryptedSek) {
const sekByte = Buffer.from(decryptedSek, 'base64');
const decipher = crypto.createDecipheriv('aes-256-ecb', sekByte, Buffer.alloc(0));
decipher.setAutoPadding(true);
let decrypted = decipher.update(data, 'base64', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
module.exports = { getSEK , encryptBySymmetricKey, decryptKey };