I need to produce the same encrypted string in Java as the one built with the Ruby encrypted_strings library. I've tried many different ways but my Java code keeps returning a different output, and I'm unable to understand what I'm doing wrong.
Below is the ruby script that produces the desired output that I can't get right in Java.
#!/usr/bin/ruby
require 'encrypted_strings'
data = 'Whackabad'
password = 'bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ'
encrypted_data = data.encrypt(:symmetric, :password => password)
printf "Data: #{data}\n"
printf "Encrypted Data: #{encrypted_data}"
Output:
Data: Whackabad
Encrypted Data: AEsDXVcgh2jsTjlDgh+REg==
I had a look at the library, and it seems to be using DES-EDE3-CBC
as the default algorithm for encryption. I deduce from here that I should use DESede
or TripleDES
algorithm and CBC
mode. As the padding option, I'm using PKCS5Padding
cause the library is calling pkcs5_keyivgen
.
Below is the Java code that tries to reproduce the same output unsuccessfully.
package ...
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
public class SymmetricDESedeCipher {
private static final String DATA = "Whackabad";
private static final String key = "bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ";
private static final String ALGORITHM = "DESede";
private static final String XFORM = "DESede/CBC/PKCS5Padding";
private static byte[] iv = new byte[8];
private static byte[] encrypt(byte[] inpBytes,
SecretKey key, String XFORM) throws Exception {
Cipher cipher = Cipher.getInstance(XFORM);
IvParameterSpec ips = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ips);
return cipher.doFinal(inpBytes);
}
public static void main(String[] unused) throws Exception {
byte[] keyBytes = key.getBytes();
DESedeKeySpec desKeySpec = new DESedeKeySpec(keyBytes);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(ALGORITHM);
SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
byte[] dataBytes = DATA.getBytes();
byte[] encBytes = encrypt(dataBytes, secretKey, XFORM);
System.out.println("Data: " + DATA);
System.out.println("Encrypted Data: " + new BASE64Encoder().encode(encBytes));
}
}
Output
Data: Whackabad
Encrypted Data: ScPTKQBsR9Ni1nJ1tsMaaQ==
I've seen people encrypting data from Java to be decrypted from Ruby and vice-versa with different algorithms so I think this can be achieved but I can't see what's wrong. Do you have an idea? If so, that'd be of much help!
Thanks