I have a server running in JAVA and I am creating a client with HTML and Javascript (about which I am less knowledgeable). The server accesses log-in credentials stored in a database with AES encryption. I need the user to enter credentials into the HTML page, then javascript to encrypt them and send them to the server, where I need to decrypt them in Java. I have found many threads online but cannot solve my problem: the encryption with JS and Java produce different results.
This is my Javascript code.
var key = "0123456789ABCDEF";
function encrypt() {
const ivMd5Hash = CryptoJS.MD5(CryptoJS.enc.Utf8.parse(key));
console.log("Hash: "+ivMd5Hash)
const cipher = this.cipher(CryptoJS.enc.Utf8.parse(value), CryptoJS.enc.Utf8.parse(key), ivMd5Hash);
return cipher.ciphertext.toString();
}
function cipher(value, key, iv) {
const cipher = CryptoJS.AES.encrypt(value, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
keySize: 128,
padding: CryptoJS.pad.Pkcs7
});
return cipher;
}
console.log("Encrypted value: "+encrypt("testuser", key);
The result from the console log is HASH: e43df9b5a46b755ea8f1b4dd08265544 Encrypted value: fc88ab1f7821b9f8c5b46ab1d41250a2
Now the JAVA part.
public class MainClass {
private static final String key = "0123456789ABCDEF";
private static String initVector = "";
public static void main(String[] args) throws Exception {
initVector=md5(key); // md5 is an external method, which works
System.out.println("HASH: "+initVector);
System.out.println("Encrypted value: "+encrypt("testuser"));
}
public static String encrypt(String value) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
return Base64.encodeBase64String(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
public static String md5(String str) {
MessageDigest messageDigest = null;
try {//from w w w . j a v a 2 s. c o m
messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(str.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException caught!");
System.exit(-1);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
byte[] byteArray = messageDigest.digest();
StringBuffer md5StrBuff = new StringBuffer();
for (int i = 0; i < byteArray.length; i++) {
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
md5StrBuff.append("0").append(
Integer.toHexString(0xFF & byteArray[i]));
else
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
}
return md5StrBuff.toString();
}
The result from the console is HASH: e43df9b5a46b755ea8f1b4dd08265544 OK Encrypted value does not appear - I get instead an InvalidAlgorithmParameterException saying the IV length must be 16 bytes long.
Can anyone help me understand why the MD5 works on JS and not on JAVA ? I would need to have in Java the same encrypted value I get from JS..
Thanks!!