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
Related
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
},
};
I want to build a function that sign a SHA512 HMAC with a Private key with a password to open that file. I have done that with Javascript but I'm not able to do it in JAVA. here is my code in Javascript:-
const fs = require('fs')
const crypto = require('crypto');
const getSignatureByInput = (input, crt) => {
let privatePem = fs.readFileSync(crt);
let key = privatePem.toString('ascii');
let sign = crypto.createSign('RSA-SHA512');
sign.write(input)
let signature = sign.sign({ key, passphrase: 'Password' }, 'hex')
return signature;
}
// Usage
let hamc = crypto.createHmac("sha512", '12345678-73a8-414c-9832-fcd4b2d9b362').update(
JSON.stringify({
"body": {
"Id": "123"
}
})
).digest("hex");
console.log(hamc)
let signatureSignedByPrivateKey = getSignatureByInput(hamc,'./private.key');
console.log(signatureSignedByPrivateKey)
and the below is the example of my private key:-
-----BEGIN ENCRYPTED PRIVATE KEY-----
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
XfJTekUHHwFnpKVang==
-----END ENCRYPTED PRIVATE KEY-----
Appreciate your support!
Thanks in advance...
I found a way to solve this thanks #pra-a for answering a question posted earlier Link here.
I will share my solution below.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.*;
import java.security.spec.*;
public class Main {
public static final String PRIVATE_KEY="./private.der";
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
// write your code here
//get the private key
File file = new File(PRIVATE_KEY);
FileInputStream fis = new FileInputStream(file);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) file.length()];
dis.readFully(keyBytes);
dis.close();
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(spec);
Mac sha512Hmac;
String result = "";
final String key = "'12345678-73a8-414c-9832-fcd4b2d9b362'";
String signature = "";
String body = "{\n" +
" \"body\": {\n" +
" \"Id\": \"123\"\n" +
" }\n" +
"}";
try {
final String HMAC_SHA512 = "HmacSHA512";
final byte[] byteKey = key.getBytes(StandardCharsets.UTF_8);
sha512Hmac = Mac.getInstance(HMAC_SHA512);
SecretKeySpec keySpec = new SecretKeySpec(byteKey, HMAC_SHA512);
sha512Hmac.init(keySpec);
byte[] macData = sha512Hmac.doFinal(body.getBytes(StandardCharsets.UTF_8));
// Can either base64 encode or put it right into hex
//result = Base64.getEncoder().encodeToString(macData);
result = bytesToHex(macData);
signature = sign(result, privKey);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
// Put any cleanup here
System.out.println("Done");
}
}
private static final char[] HEX_ARRAY = "0123456789abcdef".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
public static PrivateKey readPrivateKeyII(String filename) throws Exception{
InputStream in = new FileInputStream(filename);
byte[] privateKeydata = new byte[in.available()];
in.read(privateKeydata);
in.close();
KeyFactory privateKeyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(privateKeydata);
PrivateKey privateKey = privateKeyFactory.generatePrivate(encodedKeySpec);
return privateKey;
}
public static String sign(String plainText, PrivateKey privateKey) throws Exception {
Signature privateSignature = Signature.getInstance("SHA512withRSA");
privateSignature.initSign(privateKey);
privateSignature.update(plainText.getBytes(StandardCharsets.UTF_8));
byte[] signature = privateSignature.sign();
return bytesToHex(signature);
}
}
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;
}
}
I am having encryption and decryption code already in place.
But now i am just going to use java encryption for encrypting the text.
And going to decrypt it in JavaScript using CryptoJS.
#Service
public class EncryptionServiceImpl extends EncryptionService {
protected static final int BLOCK_SIZE_BYTES = 16;
protected static final int BLOCK_SIZE_BITS = 128;
protected SecureRandom secureRandom;
protected int keySizeByte;
#Value("${encryption.key}")
private String keyString ;
public EncryptionServiceImpl() {
byte[] key = keyString.getBytes();
//create secret key spec instance
secretKeySpec = new SecretKeySpec(key, "AES");
try {
cipher = javax.crypto.Cipher.getInstance("AES/CTR/NoPadding");
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
}
//create secure random number generator instance
secureRandom = new SecureRandom();
}
public String encrypt(String data) {
byte[] dataByte = new byte[0];
try {
dataByte = data.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
}
//create iv
SecureRandom randomSecureRandom;
IvParameterSpec ivParams = null;
byte[] iv = new byte[0];
try {
randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
ivParams = new IvParameterSpec(iv);
} catch (NoSuchAlgorithmException e) {
}
try {
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKeySpec, ivParams);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw e;
}
//return concatenation of iv + encrypted data
byte[] encByteArr;
try {
encByteArr = ArrayUtils.addAll(iv, cipher.doFinal(dataByte));
} catch (IllegalBlockSizeException | BadPaddingException e) {
throw e;
}
return Base64.encodeBase64URLSafeString(encByteArr);
}
public String decrypt(String encryptedData) {
byte[] decodedValue = Base64.decodeBase64(encryptedData);
byte[] iv = new byte[BLOCK_SIZE_BYTES];
System.arraycopy(data, 0, iv, 0, BLOCK_SIZE_BYTES);
try {
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(iv));
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
}
//return decrypted value
byte[] decryptedByteArray;
try {
decryptedByteArray = cipher.doFinal(data, BLOCK_SIZE_BYTES, data.length - BLOCK_SIZE_BYTES);
} catch (IllegalBlockSizeException | BadPaddingException e) {
}
try {
return new String(decryptedByteArray,"UTF-8");
} catch (UnsupportedEncodingException e) {
}
return new String(decryptedByteArray);
}
}
I want to do the exact decryption in JS that what i did in java.
I am new to JS.
i am trying below things to convert it in js.
I think looking at the code, i need to get rid of IV from encrypted text. but IV generated with SecureRandom. Unable to figure out how to get the rid of IV in JS.
import CryptoJS from 'crypto-js';
/* eslint-disable no-restricted-globals */
function decryption(val) {
const encrypted = CryptoJS.enc.Base64.parse(val);
const key = CryptoJS.enc.Base64.parse("<my encryption key used in java code>");
const iv = CryptoJS.enc.Base64.parse(val);
const valueDec = CryptoJS.enc.Utf8.stringify(CryptoJS.AES.decrypt(
{ ciphertext: encrypted },
key,
{ mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding, iv: iv, }));
return valueDec;
}
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();
};