I have the following code in java for encrypting the plain text :
private static final String SECRET_KEY = "SecKeyTest";
private static final String SALT = "thisIsSalt";
public String encrypt(String strToEncrypt) {
try {
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(SECRET_KEY.toCharArray(), SALT.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128 , iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmParameterSpec);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
I have to rewrite the same using NodeJs , what i have did so far :
const salt = "thisIsSalt";
const digest = 'sha256';
const aesSecretKey = "SecKeyTest";
module.exports = {
encrypt: function (plainText){
const key = crypto.pbkdf2Sync(aesSecretKey, salt, 65536, 32, digest); //key len 32bytes i.e 256bits
const iv = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]);
// AES 256 GCM Mode
var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
// encrypt the given text
var encrypted = Buffer.concat([cipher.update(plainText, 'utf8'), cipher.final()]);
// extract the auth tag
var tag = cipher.getAuthTag();
// generate output
return Buffer.concat([Buffer.from(salt), iv, tag, encrypted]).toString('base64');
}
};
For input: "hello" :
Java: rgCx2SDSqio15M+0lViNAzW/lUmz
Node: dGhpc0lzU2FsdAAAAAAAAAAAAAAAAAAAAADSqio15M+0lViNAzW/lUmzrgCx2SA=
The Java code implicitly concatenates ciphertext and tag in this order. So to get the same result in the NodeJS code, the following change would be necessary:
return Buffer.concat([encrypted, tag]).toString('base64');
However, salt and IV should not be static, but should be randomly generated for each key derivation and encryption. Since salt and IV are needed for decryption and both are not secret, they are passed along with the ciphertext and tag, typically also concatenated, e.g.: salt | iv | ciphertext | tag.