Solution
Here we have taken the Java code performing a URL decoding of the encrypted data, followed by a Base64 decoding.
IV represents the first 16 bytes of the result, while the rest represent as ciphertext.
The key is Base64 decoded.
The use of key and IV will allow you to decrypt the ciphertext with AES in PKCS#7 padding and CBC code.
Decode the decrypted data with UTF-8.
You can extract the patientid (the data after the _) and the paymentid (the data before the _) from the resulting string.
This will help you to determine the logic for the encryption:
Base64 decoding of the key
Generation of a random 16 bytes IV
Use of Key and IV for encryption with aes-256-cbc (AES-256 because of the 32 bytes key)
IV and ciphertext concatenation
Base64 encoding of the ciphertext with subsequent URL encoding
NodeJS Implementation
The following is the possible NodeJS implementation:
var crypto = require('crypto') function paymentIdencryption(text) { const secret_key = "EiE0BVQle0xFjZvYOupKjFGHAcAwBaTjlZ7G7rryNos="; const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(secret_key, 'base64'), iv); const encrypted = Buffer.concat([iv, cipher.update(text, 'utf8'), cipher.final()]); return encodeURIComponent(encrypted.toString('base64')) } console.log(paymentIdencryption("1384220_8089105")); |
The following is the possible output (changes for each encryption because of the random IV) you might get:
5I43wWYs84XQk9Pe0IMl4g%2B7s%2BgwcJrPsWo9gcX25y8%3D |
Java code:
You can test it with the Java code as well:
public class Main { public static void main(String[] args) throws Exception {
var encodedPaymentInfo = "5I43wWYs84XQk9Pe0IMl4g%2B7s%2BgwcJrPsWo9gcX25y8%3D"; var encodedKey = "EiE0BVQle0xFjZvYOupKjFGHAcAwBaTjlZ7G7rryNos=";
var encryptedPaymentInfo = java.net.URLDecoder.decode(encodedPaymentInfo,"UTF-8"); var decodedKey = java.util.Base64.getDecoder().decode(encodedKey.getBytes("UTF-8")); var decodedcipher = java.util.Base64.getDecoder().decode(encryptedPaymentInfo.getBytes("UTF-8"));
var cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding"); var secretKey = new javax.crypto.spec.SecretKeySpec(decodedKey, "AES"); var iv = new javax.crypto.spec.IvParameterSpec(decodedcipher,0,16); cipher.init(javax.crypto.Cipher.DECRYPT_MODE,secretKey,iv);
var decryptedPaymentInfo = cipher.doFinal(decodedcipher, 16, decodedcipher.length-16); var paymentInfo = new java.lang.String(decryptedPaymentInfo,"UTF-8"); var patientId = paymentInfo.substring(paymentInfo.indexOf("_")+1, paymentInfo.length()); var paymentId = paymentInfo.substring(0, paymentInfo.indexOf("_"));
System.out.println("cvs.spl.patientId: " + patientId); System.out.println("cvs.spl.paymentId: " + paymentId); } } |
Output:
cvs.spl.patientId: 8089105
cvs.spl.paymentId: 1384220
which is equal to the data of the original plaintext.
Answered by: >NotARobot
Credit: >StackOverflow
Suggested Blogs
>How to persist data between two different requests in a controller?
>How to fix routes in Laravel?>Setup checkbox for multiple switch on change in Javascript