2017-02-22 7 views
1

Мне нужно создать ту же зашифрованную строку в 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, и наоборот, с различными алгоритмами, так что я думаю, что это может быть достигнуто, но я не могу увидеть, что неправильно. У вас есть идея? Если это так, это будет очень полезно!

Благодаря

+0

Start путем обеспечения вы используете одни и те же байты. Строковые представления сильно различаются между языками. – chrylis

+1

Вы абсолютно уверены, что хотите использовать эту рубиновую библиотеку шифрования? Документация, похоже, указывает, что она выводит вектор инициализации из пароля, что является ужасной идеей - [IV должен быть случайным] (http://crypto.stackexchange.com/a/82) – dnault

+0

Да @dnault, это наследие, что Я пытаюсь перевести на Java, чтобы этот метод использовался в данный момент и тот, который я хочу воспроизвести. – rakemous

ответ

1

Первое, что нужно сделать, это derive the IV and key из данного пароля.

По ссылке выше вы получите кодировку IV и KEY, которые соответствуют "VDiJjncs4ak=" и "s9e42J3PpmQv8n5T8L3zzuFaGdrzK/wU" соответственно. Это означает, что ключ и вектор IV, используемые в коде Java, неверны, как было сказано в комментариях.

Ниже полученный Java-код:

public class SymmetricDESedeCipher { 
    private static final String DATA = "Whackabad"; 
    private static final String ALGORITHM = "DESede"; 
    private static final String XFORM = "DESede/CBC/PKCS5Padding"; 
    private static final String KEY = "s9e42J3PpmQv8n5T8L3zzuFaGdrzK/wU"; 
    private static final String IV = "VDiJjncs4ak="; 

    private static byte[] encrypt(String data, 
            SecretKey key, String XFORM, byte[] iv) throws Exception { 
     Cipher cipher = Cipher.getInstance(XFORM); 
     cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv)); 
     return cipher.doFinal(data.getBytes()); 
    } 

    public static void main(String[] unused) throws Exception { 
     DESedeKeySpec spec = new DESedeKeySpec(new BASE64Decoder().decodeBuffer(KEY)); 
     SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(ALGORITHM); 
     SecretKey secretKey = secretKeyFactory.generateSecret(spec); 

     byte[] encBytes = encrypt(DATA, secretKey, XFORM, new BASE64Decoder().decodeBuffer(IV)); 

     System.out.println("Data: " + DATA); 
     System.out.println("Encrypted Data: " + new BASE64Encoder().encode(encBytes)); 
    } 
} 

Выход:

Data: Whackabad 
Encrypted Data: AEsDXVcgh2jsTjlDgh+REg== 
Смежные вопросы