function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Deepika S 33Deepika S 33 

GST Portal Integration


Hello.. I just need a help from you all,
I am integrating Salesforce with GST Portal (2 way connection) via Rest Integration. I am stuck with Public Key Encryption Method. 
If you have already worked on it , pls let me know. Your help means alot.
 
Rosie RosieRosie Rosie
GST API is an application programming interface under GST. An API acts as an intermediary between two applications so that they can interact with each other. API is an essential aspect of easing GST compliance. https://www.gomedicare.care/
SwethaSwetha (Salesforce Developers) 
HI Deepika,
Can you share details on where specifically you are stuck? Are you seeing any errors?

Related: https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_classes_restful_crypto.htm

Thanks
Deepika S 33Deepika S 33

Hi Swetha,

I have to connect Salesforce to GST Portal to generate e-way bill.
For Authentication API, GST Portal gives the public key and also they provide Sample Java code. They use RSA Algorithm to generate public key.  While i convert the java into apex class, i used static resource to upload the public key, In my apex public key was decoded into Base64.   While passing the public key to encrypted, i am facing some errors like Key must be 16 bytes. I am unable to properly encode the public key. 


Java:
// To create Public key

public static PublicKey getPublicKey() throws FileNotFoundException, IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
FileInputStream in = new FileInputStream("<Path to File>/xxxxx_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;
}

To Create Assymetric Key

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

My Apex Class:
To create public key
String pubKey = '';
List<StaticResource> pemFiles = [SELECT Body FROM StaticResource WHERE Name = 'xxxxxxx'];
 String pemString = pemFiles[0].Body.toString();
system.debug(pemString);
string pubKey = pemString.replaceAll('(-+BEGIN PUBLIC KEY-+\r?\n|-+END PUBLIC KEY-+\r?\n?)', '');
system.debug('ded' + pubKey);
Blob publicKey = EncodingUtil.base64Encode(pubKey);

To create SEK:
Blob encryptedkey = Crypto.encryptWithManagedIV('AES128', publicKey, data);
String encodedKey = EncodingUtil.base64Encode(encryptedkey);
Blob enc = Blob.valueOf(encodedKey);
System.debug(enc);

Error i faced:
Public Key must be 16 bytes

 

Shri RajShri Raj
The error "Public Key must be 16 bytes" is occurring because the code is using AES encryption, which requires the key length to be 16 bytes. However, the public key generated from the provided sample Java code is not 16 bytes.
In order to resolve this issue, you need to make sure that the public key is of the required length. One way to do this is by using a key size of 2048 bits, which will generate a public key of 256 bytes, which can then be truncated to the required length of 16 bytes.
// To create Public key
public static PublicKey getPublicKey() throws FileNotFoundException, IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
FileInputStream in = new FileNotFoundException("<Path to File>/xxxxx_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");
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair pair = keyGen.generateKeyPair();
PublicKey publicKey = pair.getPublic();
return publicKey;
}

// To create SEK
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;
}

// Apex Class
// To create public key
String pubKey = '';
List<StaticResource> pemFiles = [SELECT Body FROM StaticResource WHERE Name = 'xxxxxxx'];
String pemString = pemFiles[0].Body.toString();
System.debug(pemString);
pubKey = pemString.replaceAll('(-+BEGIN PUBLIC KEY-+\r?\n|-+END PUBLIC KEY-+\r?\n?)', '');
System.debug('ded' + pubKey);
Blob publicKey = EncodingUtil.base64Encode(pubKey);

// To create SEK
Blob encryptedkey = Crypto.encryptWithManagedIV('AES128', publicKey.toString().substring(0,16).getBytes(), data);
String encodedKey = EncodingUtil.base64Encode(encryptedkey);
Blob enc = Blob.valueOf(encodedKey);
System.debug(enc);