In this post we a going to encrypt a message in Java and decrypt later with JavaScript.
Let's start with the Java (encryption) part:
import static org.assertj.core.api.Assertions.assertThat;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import org.assertj.core.api.Assertions;
import org.junit.Test;
public class AppveyorEncryptionTest {
private char[] password = "0123456789abcdef0123456789abcdef".toCharArray();
private byte[] salt = "0123456789".getBytes();
private int iterationCount = 5;
public static byte[] encrypt(String toEncrypt, String key) throws Exception {
// create a binary key from the argument key (seed)
SecureRandom sr = new SecureRandom(key.getBytes());
KeyGenerator kg = KeyGenerator.getInstance("Rijndael");
kg.init(sr);
SecretKey sk = kg.generateKey();
// create an instance of cipher
Cipher cipher = Cipher.getInstance("Rijndael");
// initialize the cipher with the key
cipher.init(Cipher.ENCRYPT_MODE, sk);
// enctypt!
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
}
public static String decrypt(byte[] toDecrypt, String key) throws Exception {
// create a binary key from the argument key (seed)
SecureRandom sr = new SecureRandom(key.getBytes());
KeyGenerator kg = KeyGenerator.getInstance("Rijndael");
kg.init(sr);
SecretKey sk = kg.generateKey();
// do the decryption with that key
Cipher cipher = Cipher.getInstance("Rijndael");
cipher.init(Cipher.DECRYPT_MODE, sk);
byte[] decrypted = cipher.doFinal(toDecrypt);
return new String(decrypted);
}
@Test
public void testRijndael() throws Exception {
byte[] encrypted = encrypt("Hello World!", "myKey");
assertThat(decrypt(encrypted, "myKey")).isEqualTo("Hello World!");
}
}
import java.nio.file.*;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class AesEncryption {
private String key = "shared_secret";
public byte[] encrypt(byte[] input) throws Exception {
byte[] keyBytes = key.getBytes();
byte[] md5Digest = MessageDigest.getInstance("MD5").digest(keyBytes);
byte[] result = null;
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(md5Digest, "AES"));
result = new byte[aesCipher.getOutputSize(input.length)];
int ctLength = aesCipher.update(input, 0, input.length, result, 0);
aesCipher.doFinal(result, ctLength);
return result;
}
public static void main(String[] args) throws Exception {
String message = "hello world";
byte[] input = message.getBytes("UTF-8");
byte[] encrypted = new AesEncryption().encrypt(input);
Files.write(Paths.get("/tmp/message.enc"), encrypted, StandardOpenOption.CREATE);
}
}
Let's compile and run the small AesEncryption
program:
$ java -c AesEncryption.java
$ java AesEncryption
This will save the encrypted message in /tmp/message.enc
.
To decrypt this message we are going to use this JavaScript program:
const crypto = require('crypto');
const fs = require('fs');
let key = 'shared_secret'
let encryptedInput = fs.readFileSync('message.enc');
let decipher = crypto.createDecipher('aes-128-ecb', key);
let output = Buffer.concat([decipher.update(encryptedInput) , decipher.final()]);
fs.writeFileSync('message', output);
That's it. We exchanged a secret message between Java and JavaScript.
Just in case you also want to do the encryption within a Node.js app - this is how you could do the encryption:
const forge = require('node-forge');
function encryptAes256Cbc(data, key, iv) {
let cipher = forge.cipher.createCipher('AES-CBC', forge.util.hexToBytes(key));
cipher.start({iv: forge.util.hexToBytes(iv)});
cipher.update(forge.util.createBuffer(data));
cipher.finish();
let bytes = cipher.output.getBytes();
return forge.util.encode64(bytes);
// return forge.util.encode64(bytes, 64); // use new lines
}
Have fun creating your secret messages…