AES/CBC/PKCS5Padding in NodeJs - javascript

I am trying to convert my java code to NodeJs code.
Facing some issues on the encryptions.
Here is my java code: compiled code
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.Base64;
public class AESCBCPKCS5Encryption {
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
public static String encrypt(String message, String key) throws GeneralSecurityException, UnsupportedEncodingException {
if (message == null || key == null) {
throw new IllegalArgumentException("text to be encrypted and key should not be null");
}
Cipher cipher = Cipher.getInstance(ALGORITHM);
byte[] messageArr = message.getBytes();
SecretKeySpec keySpec = new SecretKeySpec(Base64.getDecoder().decode(key), "AES");
byte[] ivParams = new byte[16];
byte[] encoded = new byte[messageArr.length + 16];
System.arraycopy(ivParams, 0, encoded, 0, 16);
System.arraycopy(messageArr, 0, encoded, 16, messageArr.length);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivParams));
byte[] encryptedBytes = cipher.doFinal(encoded);
encryptedBytes = Base64.getEncoder().encode(encryptedBytes);
return new String(encryptedBytes);
}
public static String decrypt(String encryptedStr, String key) throws GeneralSecurityException, UnsupportedEncodingException {
if (encryptedStr == null || key == null) {
throw new IllegalArgumentException("text to be decrypted and key should not be null");
}
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new
SecretKeySpec(Base64.getDecoder().decode(key), "AES");
byte[] encoded = encryptedStr.getBytes();
encoded = Base64.getDecoder().decode(encoded);
byte[] decodedEncrypted = new byte[encoded.length - 16];
System.arraycopy(encoded, 16, decodedEncrypted, 0, encoded.length - 16);
byte[] ivParams = new byte[16];
System.arraycopy(encoded, 0, ivParams, 0, ivParams.length);
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivParams));
byte[] decryptedBytes = cipher.doFinal(decodedEncrypted);
return new String(decryptedBytes);
}
public static void main(String[] args) throws GeneralSecurityException, UnsupportedEncodingException {
String str = "<Request xmlns=\"http://www.kotak.com/schemas/CorpCCPaymentsOTP/CorpCCPaymentsOTP.xsd\" ><username>ENKASH</username><password>Corp#123</password><SrcAppCd>ENKA SH</SrcAppCd><RefNo>Ref1111111111</RefNo><CardNo>4280933990002698</CardNo ><OTP>12345</OTP></Request>";
String key = "e3a74e3c7599f3ab4601d587bd2cc768";
String enc = encrypt(str, key);
System.out.println(enc);
String dec = decrypt(enc, key);
System.out.println(dec);
}
}
Here is my javascript code:
var crypto = require('crypto');
function getAlgorithm(keyBase64) {
var key = Buffer.from(keyBase64, 'base64');
switch (key.length) {
case 16:
return 'aes-128-cbc';
case 32:
return 'aes-256-cbc';
}
throw new Error('Invalid key length: ' + key.length);
}
function encrypt(plainText, keyBase64, ivBase64) {
const key = Buffer.from(keyBase64, 'base64');
const iv = Buffer.from(ivBase64, 'base64');
const cipher = crypto.createCipheriv(getAlgorithm(keyBase64), key, iv);
let encrypted = cipher.update(plainText, 'utf8', 'base64');
encrypted += cipher.final('base64');
return encrypted;
}
function decrypt(messagebase64, keyBase64, ivBase64) {
const key = Buffer.from(keyBase64, 'base64');
const iv = Buffer.from(ivBase64, 'base64');
const decipher = crypto.createDecipheriv(getAlgorithm(keyBase64), key, iv);
let decrypted = decipher.update(messagebase64, 'base64');
decrypted += decipher.final();
return decrypted;
}
var keyBase64 = "DWIzFkO22qfVMgx2fIsxOXnwz10pRuZfFJBvf4RS3eY=";
var ivBase64 = 'e3a74e3c7599f3ab4601d587bd2cc768';
var plainText = '<Request xmlns="http://www.kotak.com/schemas/CorpCCPaymentsOTP/CorpCCPaymentsOTP.xsd"><username>ENKASH</username><password>Corp#123</password><SrcAppCd>ENKA SH</SrcAppCd><RefNo>Ref1111111111</RefNo><CardNo>4280933990002698</CardNo ><OTP>12345</OTP></Request>';
var cipherText = encrypt(plainText, keyBase64, ivBase64);
var decryptedCipherText = decrypt(cipherText, keyBase64, ivBase64);
console.log('Algorithm: ' + getAlgorithm(keyBase64));
console.log('Plaintext: ' + plainText);
console.log('Ciphertext: ' + cipherText);
console.log('Decoded Ciphertext: ' + decryptedCipherText);
Encryptions throwing errors,
What I am doing wrong here?

Initialization vector length of AES in CBC mode is 16 Bytes, code in JAVA takes first 16 bytes of IV however for node.js code it uses all 24 bytes of IV, hence an error. try this code
var crypto = require('crypto');
function getAlgorithm(keyBase64) {
var key = Buffer.from(keyBase64, 'base64');
switch (key.length) {
case 16:
return 'aes-128-cbc';
case 32:
return 'aes-256-cbc';
}
throw new Error('Invalid key length: ' + key.length);
}
function encrypt(plainText, keyBase64, ivBase64) {
const key = Buffer.from(keyBase64, 'base64');
const iv = Buffer.from(ivBase64, 'base64');
const cipher = crypto.createCipheriv(getAlgorithm(keyBase64), key, iv.slice(0, 16));
let encrypted = cipher.update(plainText, 'utf8', 'base64');
encrypted += cipher.final('base64');
return encrypted;
}
function decrypt(messagebase64, keyBase64, ivBase64) {
const key = Buffer.from(keyBase64, 'base64');
const iv = Buffer.from(ivBase64, 'base64');
const decipher = crypto.createDecipheriv(getAlgorithm(keyBase64), key, iv.slice(0, 16));
let decrypted = decipher.update(messagebase64, 'base64');
decrypted += decipher.final();
return decrypted;
}
var keyBase64 = "DWIzFkO22qfVMgx2fIsxOXnwz10pRuZfFJBvf4RS3eY=";
var ivBase64 = 'e3a74e3c7599f3ab4601d587bd2cc768';
var plainText = '<Request xmlns="http://www.kotak.com/schemas/CorpCCPaymentsOTP/CorpCCPaymentsOTP.xsd"><username>ENKASH</username><password>Corp#123</password><SrcAppCd>ENKA SH</SrcAppCd><RefNo>Ref1111111111</RefNo><CardNo>4280933990002698</CardNo ><OTP>12345</OTP></Request>';
var cipherText = encrypt(plainText, keyBase64, ivBase64);
var decryptedCipherText = decrypt(cipherText, keyBase64, ivBase64);
console.log('Algorithm: ' + getAlgorithm(keyBase64));
console.log('Plaintext: ' + plainText);
console.log('Ciphertext: ' + cipherText);
console.log('Decoded Ciphertext: ' + decryptedCipherText);

in java key converted in 16 byte so 'AES/CBC/PKCS5Padding' algo applied while in nodejs this is convered into 24 byte so we need to apply 'aes-192-cbc'.
var crypto = require('crypto');
const encrypt = (plainText, keyBase64) =>{
const textBuffer = Buffer.from(plainText);
const key = Buffer.from(keyBase64, 'base64');
var iv = Buffer.from([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
var encoded = Buffer.concat([iv,textBuffer]);
const cipher = crypto.createCipheriv('aes-192-cbc', key, iv);
let encrypted = cipher.update(encoded, 'binary', 'base64')
encrypted += cipher.final('base64');
return encrypted;
};
const decrypt = (messagebase64, keyBase64) =>{
const key = Buffer.from(keyBase64, 'base64');
const encoded = Buffer.from(messagebase64, 'base64');
var iv = encoded.slice(0, 16);
var decoded = encoded.slice(16,encoded.length);
const decipher = crypto.createDecipheriv('aes-192-cbc', key, iv);
let decrypted = decipher.update(decoded, 'binary','utf-8');
decrypted += decipher.final();
return decrypted;
}
String str = "<Request xmlns=\"http://www.kotak.com/schemas/CorpCCPaymentsOTP/CorpCCPaymentsOTP.xsd\" ><username>ENKASH</username><password>Corp#123</password><SrcAppCd>ENKA SH</SrcAppCd><RefNo>Ref1111111111</RefNo><CardNo>4280933990002698</CardNo ><OTP>12345</OTP></Request>";
String key = "e3a74e3c7599f3ab4601d587bd2cc768";
console.log("input: "+str);
const hash = encrypt(str,key);
console.log("encrypted::: " + hash);
const text = decrypt(hash,key);
console.log("output: "+text);

This is the solution for the above issue. I was getting the decryption error whenever I encrypt using the above code. I made a small update in the code by adding 16 characters at the start of plain text while encrypting.
var crypto = require('crypto');
function getAlgorithm(keyBase64) {
var key = Buffer.from(keyBase64, 'base64');
switch (key.length) {
case 16:
return 'aes-128-cbc';
case 32:
return 'aes-256-cbc';
}
throw new Error('Invalid key length: ' + key.length);
}
function encrypt(plainText, keyBase64, ivBase64) {
const key = Buffer.from(keyBase64, 'base64');
const iv = Buffer.from(ivBase64, 'base64');
const cipher = crypto.createCipheriv(getAlgorithm(keyBase64), key, iv);
let encrypted = cipher.update(iv.subarray(0, 16) + plainText, 'utf8', 'base64')
encrypted += cipher.final('base64');
return encrypted;
};
function decrypt(messagebase64, keyBase64, ivBase64) {
const key = Buffer.from(keyBase64, 'base64');
const iv = Buffer.from(ivBase64, 'base64');
const decipher = crypto.createDecipheriv(getAlgorithm(keyBase64), key, iv);
let decrypted = decipher.update(messagebase64, 'base64');
decrypted += decipher.final();
return decrypted;
}
var keyBase64 = "DWIzFkO22qfVMgx2fIsxOXnwz10pRuZfFJBvf4RS3eY=";
var ivBase64 = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).toString('base64');;
var plainText = '<Request xmlns="http://www.kotak.com/schemas/CorpCCPaymentsOTP/CorpCCPaymentsOTP.xsd"><username>ENKASH</username><password>Corp#123</password><SrcAppCd>ENKA SH</SrcAppCd><RefNo>Ref1111111111</RefNo><CardNo>4280933990002698</CardNo ><OTP>12345</OTP></Request>';
var cipherText = encrypt(plainText, keyBase64, ivBase64);
var decryptedCipherText = decrypt(cipherText, keyBase64, ivBase64);
console.log('Algorithm: ' + getAlgorithm(keyBase64));
console.log('Plaintext: ' + plainText);
console.log('Ciphertext: ' + cipherText);
console.log('Decoded Ciphertext: ' + decryptedCipherText);

Related

AES/GCM/NoPadding encryption in JAVA & decryption in JavaScript

I am using AES/GCM/NoPadding 128 bit. I want to encrypt in Java & decrypt it in Javascript.
When I encrypt in JS & try to decrypt in Java I get the error as Tag mismatch!null
When I encrypt in Java & try to decrypt in JS I get the error as
internal/crypto/cipher.js:164
const ret = this._handle.final();
^
Error: Unsupported state or unable to authenticate data
at Decipheriv.final (internal/crypto/cipher.js:164:28)
at decrypt (/tmp/HoErdq6TQ2.js:51:58)
What am I missing in my JS
Please suggest fixes in JS code, Java code can't be changed as it is in use on production
Java code:
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Arrays;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import java.util.logging.Logger;
import java.util.Base64;
public class HelloWorld {
private final static Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
public static void main(String []args) {
String masterKey = "2f12cb0f1d2e3d12345f1af2b123dce4";
String encrypted = aesEncryptStringV2("Hello, World!", masterKey);
System.out.println(encrypted);
String decrypted = aesDecryptStringV2(encrypted, masterKey);
System.out.println(decrypted);
}
private static final String ALGORITHM = "AES/GCM/NoPadding";
private static final int GCM_IV_LENGTH = 12;
private static final int GCM_TAG_LENGTH = 16;
private static SecretKeySpec setKeyV2(final String myKey) {
try {
byte[] newKey = myKey.getBytes(StandardCharsets.UTF_8);
MessageDigest sha = MessageDigest.getInstance("SHA-512");
newKey = sha.digest(newKey);
newKey = Arrays.copyOf(newKey, 16);
return new SecretKeySpec(newKey, "AES");
} catch (Exception e) {
System.out.println("Error in setKeyV2: ");
System.out.println(e.getMessage());
}
return null;
}
public static synchronized String aesEncryptStringV2(
final String strToEncrypt, final String secret) {
try {
SecretKeySpec newSecretKey = setKeyV2(secret);
Cipher cipher = Cipher.getInstance(ALGORITHM);
GCMParameterSpec gcmParameterSpec = new
GCMParameterSpec(GCM_TAG_LENGTH * 8,
new byte[GCM_IV_LENGTH]);
cipher.init(Cipher.ENCRYPT_MODE, newSecretKey, gcmParameterSpec);
return Base64.getEncoder()
.encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8
)));
} catch (Exception e) {
System.out.println("Error in aesEncryptStringV2: ");
System.out.println(e.getMessage());
}
return null;
}
public static synchronized String aesDecryptStringV2(
final String strToDecrypt, final String secret) {
try {
SecretKeySpec newSecretKey = setKeyV2(secret);
Cipher cipher = Cipher.getInstance(ALGORITHM);
GCMParameterSpec gcmParameterSpec = new
GCMParameterSpec(GCM_TAG_LENGTH * 8,
new byte[GCM_IV_LENGTH]);
cipher.init(Cipher.DECRYPT_MODE, newSecretKey, gcmParameterSpec);
return new
String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
} catch (Exception e) {
System.out.println("Error in aesDecryptStringV2: ");
System.out.println(e.getMessage());
}
return null;
}
}
Javascript Code:
const crypto = require('crypto');
const cryptoConfig = {
cipherAlgorithm: 'aes-128-gcm',
masterKey: '2f12cb0f1d2e3d12345f1af2b123dce4',
ivLength: 12,
tagLength: 16,
digest: 'sha512'
}
const generateKey = () => {
var h = crypto.createHash(cryptoConfig.digest);
h.update(cryptoConfig.masterKey, 'utf8');
var k = h.digest().slice(0, 16);
return k;
};
function encrypt(content) {
const iv = crypto.randomBytes(cryptoConfig.ivLength);
const key = generateKey();
const cipher = crypto.createCipheriv(cryptoConfig.cipherAlgorithm, key, iv, {authTagLength: cryptoConfig.tagLength});
const encrypted = Buffer.concat([cipher.update(content, 'utf8'), cipher.final()]);
const tag = cipher.getAuthTag();
return Buffer.concat([iv, encrypted, tag]).toString('base64');
}
const decrypt = (encdata, masterkey) => {
const bData = Buffer.from(encdata, 'base64');
const iv = bData.slice(0, 12);
const tag = bData.slice(bData.length - 16, bData.length);
const text = bData.slice(12, bData.length - 16);
const key = generateKey(masterkey);
const decipher = crypto.createDecipheriv('aes-128-gcm', key, iv);
decipher.setAuthTag(tag);
const decrypted =
decipher.update(text, 'binary', 'utf8') + decipher.final('utf8');
return decrypted;
};
const encryptedData = encrypt('hello world');
console.log('encrypt data -> ', encryptedData);
const decryptedData = decrypt(encryptedData);
console.log('decryptedData -> ', decryptedData);
So the Java code doesn't attach IV/nonce to the output. It uses a buffer of 0's of specified length.
Updated JS decryption code:
const decrypt = (encdata, masterkey) => {
const bData = Buffer.from(encdata, 'base64');
const iv = Buffer.alloc(12);
const tag = bData.slice(bData.length - 16, bData.length);
const text = bData.slice(0, bData.length - 16);
const key = generateKey(masterkey);
const decipher = crypto.createDecipheriv('aes-128-gcm', key, iv);
decipher.setAuthTag(tag);
const decrypted =
decipher.update(text, 'binary', 'utf8') + decipher.final('utf8');
return decrypted;
};
Serious security warning: Do NOT use the above code in production as it is UNSECURE. You should consider to change your production code as the encryption in AES GCM mode gets total insecure when using a nonce more than one time with the same key (the Java code is using a static IV/nonce)
Credits - Michael Fehr's comment

I'am Getting 'bad decrypt' error In Node.js

const crypto = require('crypto')
class encryptedDataClass {
constructor(massage){
this.algorithm = 'aes-256-cbc'
this.initVector = crypto.randomBytes(16);
this.massage = massage;
this.Securitykey = crypto.randomBytes(32);
}
encrypted(){
const cipher = crypto.createCipheriv(this.algorithm, this.Securitykey, this.initVector);
let encryptedData = cipher.update(this.massage, "utf-8", "hex");
return encryptedData += cipher.final("hex");
}
decrypted(){
const decipher = crypto.createDecipheriv(this.algorithm, this.Securitykey,
this.initVector);
let decryptedData = decipher.update(this.massage, "hex", "utf-8");
return decryptedData += decipher.final("utf-8");
}
}
const secureName = new
encryptedDataClass("850749d212e39c8e24aee37bbb43e3c1eaee69ea592eeaeb93da5c83437f64a0")
console.log(secureName.decrypted())
I created that key using encrypted function but I can't decode that key, I'm getting an error:
06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
How can I fix this error?
As AKX mentioned, you're creating a new IV everytime and when decrypting, you need the original IV. See my solution below. I'm storing the IV and later retrieving it by splitting the string on the "."
const crypto = require("crypto");
const algorithm = "aes-192-cbc"; // algorithm to use
const password = 'defineaPassword';
const key = crypto.scryptSync(password, 'salt', 24); // create key
const iv = crypto.randomBytes(16); // generate different ciphertext everytime
module.exports = {
encryptAndBase64 (messagetext) {
try {
const iv = crypto.randomBytes(16); // generate different ciphertext everytime
const cipher = crypto.createCipheriv(algorithm, key, iv);
const ciphertext = cipher.update(messagetext, 'utf8', 'hex') + cipher.final('hex'); // encrypted text
return `${iv.toString('base64')}.${ciphertext}`;
} catch (e) {
console.log(`error while encrypting: ${e.message}`);
return messagetext;
}
},
decrypt (messagetext) {
const split = messagetext.split('.');
const iv = split[0];
messagetext = split[1];
const decipher = crypto.createDecipheriv(algorithm, key, Buffer.from(iv, 'base64'));
return decipher.update(messagetext, 'hex', 'utf8') + decipher.final('utf8'); // deciphered text
},
};

Malformed UTF-8 data when decoding a BASE64 to String with ciphertext

I want to decode a BASE64 to String with ciphertext, key, and iv using Crypto-JS. I get the error Malformed UTF-8 data.
My code:
const CryptoJS = require('crypto-js')
const fs = require('fs');
// BASE64
const str = fs.readFileSync('file.txt','utf8')
const genRanHex = function(_0x8d0344) {
for (var _0x15f7b3 = [], _0x2491b5 = '0123456789abcdef', _0x2b0a63 = 0x0; _0x2b0a63 < _0x8d0344; _0x2b0a63++) _0x15f7b3['push'](_0x2491b5['charAt'](Math['floor'](Math['random']() * _0x2491b5['length'])));
return _0x15f7b3['join']('');
}
var KEYS = genRanHex(0x10) + '3c07f4b0efef700a',
ciphertext = str['substring'](0x18),
key = CryptoJS['enc']['Hex']['parse'](KEYS),
iv = CryptoJS.enc.Base64.parse(str.substring(0x0, 0x18))
try {
const decrypted = CryptoJS.AES.decrypt(ciphertext, key, {iv }).toString(CryptoJS.enc.Utf8);
var originalText = JSON.parse(decrypted)
console.log(originalText)
} catch (err) {
console.error(err)
}

AES256 NodeJS Decrypt

My clean data is : Test12345678910
My secret key is : 12345678901234561234567890123456
When i encrypt the data i get this output : ldJbAK2rYjDnS6kWz2O+Aw==
when i decrypt it i get error
internal/crypto/cipher.js:164
const ret = this._handle.final();
^
Error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
my code is ;
const crypto = require('crypto');
const encrypted = "ldJbAK2rYjDnS6kWz2O+Aw==";
const key = "12345678901234561234567890123456";
let decipher = crypto.createDecipher('aes-256-cbc', key);
let decrypted = decipher.update(encrypted);
decrypted = [decrypted, decipher.final("utf-8")];
console.log(decrypted.toString());
Encrypting from C#
public static string EncryptToken(string text)
{
string confkey = "12345678901234561234567890123456";
byte[] array;
try
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(confkey);
aes.IV = new byte[16];
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
{
streamWriter.Write(text);
}
array = memoryStream.ToArray();
}
}
}
return Convert.ToBase64String(array);
}
catch
{
return string.Empty;
}
}

how to decrypt in nodejs which is encrypted using JAVA

im trying to convert java lambda into javascript lamda. want to convert these encrypt and decrypt method which is written in java to node js or javascript.
I have tried to implement using crpto in node
keys are like this
private static String CIPHER_NAME = "AES/CBC/PKCS5PADDING";
private static int CIPHER_KEY_LEN = 16; //128 bits
encrypt method
private String encrypt(String key, String iv, String data) {
try {
if (key.length() <CIPHER_KEY_LEN) {
int numPad = CIPHER_KEY_LEN - key.length();
for(int i = 0; i < numPad; i++){
key += "0"; //0 pad to len 16 bytes
}
} else if (key.length() >CIPHER_KEY_LEN) {
key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
}
IvParameterSpec initVector = new IvParameterSpec(iv.getBytes("ISO-8859-1"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ISO-8859-1"), "AES");
Cipher cipher = Cipher.getInstance(CIPHER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, initVector);
byte[] encryptedData = cipher.doFinal((data.getBytes()));
String base64_EncryptedData = Base64.getEncoder().encodeToString(encryptedData);
String base64_IV = Base64.getEncoder().encodeToString(iv.getBytes("ISO-8859-1"));
return base64_EncryptedData + ":" + base64_IV;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
decrypt method
private String decrypt(String key, String data) {
try {
if (key.length() < CIPHER_KEY_LEN) {
int numPad = CIPHER_KEY_LEN - key.length();
for(int i = 0; i < numPad; i++){
key += "0"; //0 pad to len 16 bytes
}
} else if (key.length() > CIPHER_KEY_LEN) {
key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
}
String[] parts = data.split(":");
IvParameterSpec iv = new IvParameterSpec(Base64.getDecoder().decode(parts[1]));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ISO-8859-1"), "AES");
Cipher cipher = Cipher.getInstance(CIPHER_NAME);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decodedEncryptedData = Base64.getDecoder().decode(parts[0]);
byte[] original = cipher.doFinal(decodedEncryptedData);
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
I have used
this is the solution i made but seems it not working cause i encrypted this using a java code and using node's javascript code to decrypt it.
function decrypt (messagebase64, keyBase64, ivBase64) {
var key = Buffer.from(keyBase64, 'base64');
var iv = Buffer.from(ivBase64, 'base64');
var decipher = crypto.createDecipheriv(getAlgorithm(keyBase64), key, iv);
decipher.setAutoPadding(false);
decipher.update(messagebase64, 'base64');
return decipher.final();
}
find the alogorithm i use this and adding padding if the key is not long enough but this give error that saying length is not enough.
function getAlgorithm(keyBase64) {
if(keyBase64.length<CIPHER_KEY_LEN){
var padding = CIPHER_KEY_LEN-keyBase64.length;
for(var i=0;i<padding;i++){
keyBase64+="0";
}
}else if(keyBase64.length>CIPHER_KEY_LEN){
keyBase64 =keyBase64.substring(0, CIPHER_KEY_LEN)
}
var key = Buffer.from(keyBase64, 'base64');
switch (key.length) {
case 16:
return 'aes-128-cbc';
case 32:
return 'aes-256-cbc';
}
throw new Error('Invalid key length: ' + key.length);
}
after struggling for a while i have implemented encrypted method and decrypt method which will be identical to java.
decrypt method
function decrypt (messagebase64, keyBase64, ivBase64) {
if(keyBase64.length<CIPHER_KEY_LEN){
var padding = CIPHER_KEY_LEN-keyBase64.length;
for(var i=0;i<padding;i++){
keyBase64+="0";
}
}else if(keyBase64.length>CIPHER_KEY_LEN){
keyBase64 =keyBase64.substring(0, CIPHER_KEY_LEN)
}
var key = Buffer.from(keyBase64, 'latin1');
var iv = Buffer.from(ivBase64, 'base64');
var encryptdata = new Buffer(messagebase64, 'base64');
var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv),
decoded = decipher.update(encryptdata, 'base64', 'utf8');
decoded += decipher.final('utf8');
return decoded
}
encrypt method
function encrypt(plainText, keyBase64, ivBase64) {
if(keyBase64.length<CIPHER_KEY_LEN){
var padding = CIPHER_KEY_LEN-keyBase64.length;
for(var i=0;i<padding;i++){
keyBase64+="0";
}
}else if(keyBase64.length>CIPHER_KEY_LEN){
keyBase64 =keyBase64.substring(0, CIPHER_KEY_LEN)
}
var key = Buffer.from(keyBase64, 'latin1');
var iv = Buffer.from(ivBase64,'latin1');
var encoded_base64_iv= iv.toString('base64');
var cipher2 = crypto.createCipheriv('aes-128-cbc', key, iv);
cipher2.write(plainText);
cipher2.end();
var cipher_text = cipher2.read();
var encodedString = cipher_text.toString('base64');
var final_encrypted_data = encodedString+":"+encoded_base64_iv;
return final_encrypted_data.toString();
};

Categories