Мне нужно создать ту же зашифрованную строку в Java, что и встроенная библиотека Ruby encrypted_strings. Я пробовал много разных способов, но мой Java-код продолжает возвращать другой результат, и я не могу понять, что я делаю неправильно.Шифровать строку в Java в соответствии с методом шифрования из encrypted_strings ruby lib
Ниже приведен скрипт ruby, который создает желаемый результат, который я не могу получить прямо на 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}"
Выход:
Data: Whackabad
Encrypted Data: AEsDXVcgh2jsTjlDgh+REg==
Я посмотрел в библиотеке, и, кажется, использует DES-EDE3-CBC
как алгоритм по умолчанию для шифрования. Я выводю здесь, что должен использовать алгоритм DESede
или TripleDES
и режим CBC
. В качестве опции дополнения я использую PKCS5Padding
, потому что библиотека вызывает pkcs5_keyivgen
.
Ниже приведен код Java, который пытается воспроизвести тот же результат неудачно.
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));
}
}
Выход
Data: Whackabad
Encrypted Data: ScPTKQBsR9Ni1nJ1tsMaaQ==
Я видел человек шифрование данных из Java, чтобы быть расшифрованы с Ruby, и наоборот, с различными алгоритмами, так что я думаю, что это может быть достигнуто, но я не могу увидеть, что неправильно. У вас есть идея? Если это так, это будет очень полезно!
Благодаря
Start путем обеспечения вы используете одни и те же байты. Строковые представления сильно различаются между языками. – chrylis
Вы абсолютно уверены, что хотите использовать эту рубиновую библиотеку шифрования? Документация, похоже, указывает, что она выводит вектор инициализации из пароля, что является ужасной идеей - [IV должен быть случайным] (http://crypto.stackexchange.com/a/82) – dnault
Да @dnault, это наследие, что Я пытаюсь перевести на Java, чтобы этот метод использовался в данный момент и тот, который я хочу воспроизвести. – rakemous