Question:
Why crypto library looks like cipher update isn’t working in Nodejs?

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


Submit
0 Answers