Reputation: 13
Since a couple of days i try to figure out why i have in javascript(cryptojs) and java different encryption output. Im at a dead end and dont know what to change anymore, i think i will lose my head on this. This is the complete code and should be easy to copy paste for testing. You are my last hope. ^^
plainText = plaintext
password = password
salt = 3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55
iv = 3C46C00F42A6044A"
Javascript result = zbohHpV5RtmHiH3cKDY15w==
Java result = wVdRQiIqkyVlttkWpCMSpQ==
Javascript html: updated and changed iterations to 10
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Aes Test</title>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/pbkdf2.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
</head>
<body>
<div id="result"></div>
</body>
<script>
var password = "password";
var salt = "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55";
var plainText = "plaintext";
var iv = "3C46C00F42A6044A";
var key = CryptoJS.PBKDF2(password, CryptoJS.enc.Hex.parse(salt), {keySize: 128/32, iterations: 10});
var a = CryptoJS.AES.encrypt(plainText, key, {iv: CryptoJS.enc.Hex.parse(iv)}).ciphertext.toString(CryptoJS.enc.Base64);
var result = "encypted: " + a + "<br \>";
document.getElementById("result").innerHTML = result;
</script>
</html>
Java Main.class
public class main {
public static void main(String[] args) throws Exception {
String result = Aes.encrypt("plaintext", "password", "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55", "3C46C00F42A6044A");
System.out.println(result);
}
}
Java Aes.class
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class Aes {
private static final int pswdIterations = 10;
private static final int keySize = 128;
public static String encrypt(String plainText, String password, String salt, String initializationVector) throws NoSuchAlgorithmException, InvalidKeySpecException, UnsupportedEncodingException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
byte[] saltBytes = salt.getBytes("UTF-8");
byte[] ivBytes = initializationVector.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, pswdIterations, keySize);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivBytes));
byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes());
return new Base64().encodeAsString(encryptedTextBytes);
}
}
Upvotes: 0
Views: 2672
Reputation: 13
Finally they are both equal thanks to pasimako to put me on the road. I had to change the way iv and salt was converted to hex and also the lenght of the iv and as mentioned above the keySize and iterationCount variables were undefined aswell.
Here is the complete working code.
They both should output:
encypted: 47S4kEkmEoMoOgngftzyFg==
Javascript
<script>
var password = "password";
var salt = "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55";
var plainText = "plaintext";
var iv = "12345678901234567890123456789012";
var key = CryptoJS.PBKDF2(password, CryptoJS.enc.Hex.parse(salt), {keySize: 128/32, iterations: 10});
var a = CryptoJS.AES.encrypt(plainText, key, {iv: CryptoJS.enc.Hex.parse(iv)}).ciphertext.toString(CryptoJS.enc.Base64);
var result = "encypted: " + a + "<br \>";
document.getElementById("result").innerHTML = result;
</script>
Java Main.class
public class main {
public static void main(String[] args) throws Exception {
String result = Aes.encrypt("plaintext", "password", "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55", "12345678901234567890123456789012");
System.out.println(result);
}
}
Java Aes.class
public class Aes {
private static final int pswdIterations = 10;
private static final int keySize = 128;
public static String encrypt(String plainText, String password, String salt, String initializationVector) throws NoSuchAlgorithmException, NoSuchPaddingException, DecoderException, InvalidKeySpecException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password.toCharArray(), Hex.decodeHex(salt.toCharArray()), pswdIterations, keySize);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(Hex.decodeHex(initializationVector.toCharArray())));
byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes());
return new Base64().encodeAsString(encryptedTextBytes);
}
}
Upvotes: 1
Reputation: 121
First of all your JavaScript code is wrong. Try the code below to see that your keySize and iterationCount variables are undefined.
Aes.generateKey = function(salt, passPhrase) {
console.log(this.keySize);
console.log(this.iterationCount);
var key = CryptoJS.PBKDF2(
passPhrase,
CryptoJS.enc.Hex.parse(salt),
{ keySize: this.keySize, iterations: this.iterationCount });
return key;
}
The result from JavaScript should be Bttn5HNBIFDQ5hb1IbOFXQ==
var password = "password";
var salt = "3FF2EC019C627B945225DEBAD71A01B6985FE84C95A70EB132882F88C0A59A55";
var plainText = "plaintext";
var iv = "3C46C00F42A6044A";
var key = CryptoJS.PBKDF2(password, CryptoJS.enc.Hex.parse(salt), {keySize: 128/32, iterations: 10000});
var a = CryptoJS.AES.encrypt(plainText, key, {iv: CryptoJS.enc.Hex.parse(iv)}).ciphertext.toString(CryptoJS.enc.Base64);
console.log(a);
Upvotes: 0