Java Encryption & JavaScript Decryption Using AES Algorithm

Jitendra Patwa
5 min readJan 19, 2020

Many days, I struggled to make client server encryption & decryption process using Java and Javascript. I had to, string must be encrypted from server and it will be passed into client and client decrypt the encrypted string using shared key. The main problem I faced which was encryption and decryption is done for the server-side. The decryption process which I was using was not giving a proper result in client-side.

After that I found many stackoverflow results, from that I found a feasible solution to overcome above problem.

Firstly, in client side Javascript require CryptoJS library. And in Java javax.crypto.* package.

In Java, we have to first set the key which should be of 16 byte.

private static final byte[] secretKey = new byte[] { ‘m’, ‘u’, ‘s’, ‘t’, ‘b’, ‘e’, ‘1’, ‘6’, ‘b’, ‘y’, ‘t’,’e’, ‘s’, ‘k’, ‘e’, ‘y’};

Above secretKey of byte array we can use in as string format to be pass in generating of SecretKeySpec in generateKey(secret) method.

And from that generate a Key to use in Cipher for encryption using AES ECB PKCS5Padding which is default loaded in encryption process in below method.

public static String encrypt(String Data, String secret) throws Exception {

Key key = generateKey(secret);

Cipher c = Cipher.getInstance(ALGO);

c.init(Cipher.ENCRYPT_MODE, key);

byte[] encVal = c.doFinal(Data.getBytes());

String encryptedValue = Base64.getEncoder().encodeToString(encVal);

return encryptedValue;

}

ALGO is “AES” & generateKey() is the method to generate key and it will use in encryption and decryption process.

private static Key generateKey(String secret) throws Exception {

byte[] decoded = Base64.getDecoder().decode(secret.getBytes());

Key key = new SecretKeySpec(decoded, ALGO);

return key;

}

Furthermore, in Javascript we need to set CryptoJS library as its uses for encryption and decryption.

From CryptoJS CDN we can use or for NodeJS we can use by command line

>npm i crypto-js

but, the problem which I faced in Javascript not in NodeJS, so therefore library using in Javascript code to decrypt the ciphertext.

Hence, we need a shared encoded base64 key from 16 byte AES length string. Below is the decryption code in javascript as follow as,

var encryptedBase64Key = <encoded base64 key from Java>;
var parsedBase64Key = CryptoJS.enc.Base64.parse(encryptedBase64Key);

var encryptedCipherText = <encrypted cipher text/string from Java>;

var decryptedData = CryptoJS.AES.decrypt( encryptedCipherText, parsedBase64Key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
} );

var decryptedText = decryptedData.toString( CryptoJS.enc.Utf8 );
console.log( “DecryptedText = “ + decryptedText );

In Javascript padding is uses default Pkcs7 as similar in Java which is Pkcs5 and mode is ECB.

So, overall the problem is solved from above approach. I am so delight to code in Java and Javascript to resolve this problem. I’m giving following example to test for the above scenario from Java to Javascript.

Encrypting a plain text “Please encrypt this message!” with 16 byte string and shared key “mustbe16byteskey”. The following encrypted cipher text will produces the Java console.

From Java code,

public static void main(String a[]) throws Exception {

String secretKey = “mustbe16byteskey”;

String encodedBase64Key = encodeKey(secretKey);

String toEncrypt = “Please encrypt this message!”;

String encrStr = Crypt.encrypt(toEncrypt, encodedBase64Key);

System.out.println(“Cipher Text: Encryption of str = “ + encrStr);

}

Output:

Ciphertext: U2WvSc8oTur1KkrB6VGNDmA3XxJb9cC+T9RnqT4kD90=

&

EncodedBase64Key: bXVzdGJlMTZieXRlc2tleQ==

And using ciphertext and encodedBase64Key shared key in Javascript passing into decryption process as given above Javascript code the plain/original message will return in the javascript console using below code.

// Decryption process
var encryptedBase64Key = ‘bXVzdGJlMTZieXRlc2tleQ==’;
var parsedBase64Key = CryptoJS.enc.Base64.parse(encryptedBase64Key);
var encryptedCipherText = ‘U2WvSc8oTur1KkrB6VGNDmA3XxJb9cC+T9RnqT4kD90=’;
var decryptedData = CryptoJS.AES.decrypt( encryptedCipherText, parsedBase64Key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
} );
// this is the decrypted data as a string
var decryptedText = decryptedData.toString( CryptoJS.enc.Utf8 );
console.log( “DecryptedText = “ + decryptedText );

“Please encrypt this message!”.

Here is the full code of encryption and decryption between above two languages.

Java:

package com.example.demo;

import java.security.Key;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class Crypt {

private static final String ALGO = “AES”; // Default uses ECB PKCS5Padding

public static String encrypt(String Data, String secret) throws Exception {
Key key = generateKey(secret);
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
String encryptedValue = Base64.getEncoder().encodeToString(encVal);
return encryptedValue;
}

public static String decrypt(String strToDecrypt, String secret) {
try {
Key key = generateKey(secret);
Cipher cipher = Cipher.getInstance(ALGO);
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
} catch (Exception e) {
System.out.println(“Error while decrypting: “ + e.toString());
}
return null;
}

private static Key generateKey(String secret) throws Exception {
byte[] decoded = Base64.getDecoder().decode(secret.getBytes());
Key key = new SecretKeySpec(decoded, ALGO);
return key;
}

public static String decodeKey(String str) {
byte[] decoded = Base64.getDecoder().decode(str.getBytes());
return new String(decoded);
}

public static String encodeKey(String str) {
byte[] encoded = Base64.getEncoder().encode(str.getBytes());
return new String(encoded);
}

public static void main(String a[]) throws Exception {
/*
* Secret Key must be in the form of 16 byte like,
*
* private static final byte[] secretKey = new byte[] { ‘m’, ‘u’, ‘s’, ‘t’, ‘b’,
* ‘e’, ‘1’, ‘6’, ‘b’, ‘y’, ‘t’,’e’, ‘s’, ‘k’, ‘e’, ‘y’};
*
* below is the direct 16byte string we can use
*/
String secretKey = “mustbe16byteskey”;
String encodedBase64Key = encodeKey(secretKey);
System.out.println(“EncodedBase64Key = “ + encodedBase64Key); // This need to be share between client and server

// To check actual key from encoded base 64 secretKey
// String toDecodeBase64Key = decodeKey(encodedBase64Key);
// System.out.println(“toDecodeBase64Key = “+toDecodeBase64Key);

String toEncrypt = “Please encrypt this message!”;
System.out.println(“Plain text = “ + toEncrypt);

// AES Encryption based on above secretKey
String encrStr = Crypt.encrypt(toEncrypt, encodedBase64Key);
System.out.println(“Cipher Text: Encryption of str = “ + encrStr);

// AES Decryption based on above secretKey
String decrStr = Crypt.decrypt(encrStr, encodedBase64Key);
System.out.println(“Decryption of str = “ + decrStr);
}
}

Javascript:

<!DOCTYPE html>
<html>
<body>

<h2>Java JavaScript Encryption & Decryption</h2>
<script type=”text/javascript” src=”https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
<script type=”text/javascript”>
console.log(‘crypto-js’, CryptoJS);

var encryptedBase64Key = ‘bXVzdGJlMTZieXRlc2tleQ==’;
var parsedBase64Key = CryptoJS.enc.Base64.parse(encryptedBase64Key);
var encryptedData = null;
{
// Encryption process
var plaintText = “Please encrypt this message!”;
// console.log( “plaintText = “ + plaintText );

// this is Base64-encoded encrypted data
encryptedData = CryptoJS.AES.encrypt(plaintText, parsedBase64Key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
console.log( “encryptedData = “ + encryptedData );
}

{
// Decryption process
var encryptedCipherText = ‘U2WvSc8oTur1KkrB6VGNDmA3XxJb9cC+T9RnqT4kD90=’ ; // or encryptedData;
var decryptedData = CryptoJS.AES.decrypt( encryptedCipherText, parsedBase64Key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
} );
// console.log( “DecryptedData = “ + decryptedData );

// this is the decrypted data as a string
var decryptedText = decryptedData.toString( CryptoJS.enc.Utf8 );
console.log( “DecryptedText = “ + decryptedText );
}

</script>
</body>
</html>

Thanks And, I apologies for bad English.

--

--