Расшифровка openssl blowfish с помощью Java - PullRequest
3 голосов
/ 12 декабря 2011

У меня есть удаленная система, отправляющая мне данные, которые она зашифровала с помощью программы командной строки openssl, используя шифрование blowfish.

В частности, запускаемая команда:

openssl enc -blowfish -a -salt -in original.txt -out encrypted.txt -pass pass:secret

Для ввода This is a test., который производит U2FsdGVkX19bSsC3dXTOYssoOK5L3THkhXgiB7X1Trv6SaVO2TGz0g==

Я пытаюсь расшифровать этот контент на другой стороне Java с помощью следующего кода.

// requires commons-io and commons-codec
public void testDecryption() throws Exception {
    File encryptedFile = new File("encrypted.txt");
    String password = "secret";

    byte[] base64EncryptedBytes = FileUtils.readFileToByteArray(encryptedFile);
    byte[] encryptedBytes = new Base64().decode(base64EncryptedBytes);

    SecretKeySpec blowfishKey = new SecretKeySpec(password.getBytes("ASCII"), "Blowfish");
    Cipher blowfishCipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
    blowfishCipher.init(Cipher.DECRYPT_MODE, blowfishKey);
    byte[] decryptedContent = blowfishCipher.doFinal(encryptedBytes);

    System.out.println(new String(decryptedContent));
}

Вместо оригинального сообщения, которое в данный момент создает ...

êõïÖ¶M≥ O]¢∞;Z<HVÖ_’˚h‘:O›c=w◊®zÉ9˘

Что я делаю не так?

Некоторые возможные теории

  • Blowfish / ECB / NoPadding - неподходящий экземпляр шифра для использования. Я пробовал все комбинации режима и заполнения, перечисленные в http://docs.oracle.com/javase/1.4.2/docs/guide/security/jce/JCERefGuide.html#AppA, за исключением OAEP с заполнением [digest] и [mgf] безуспешно.
    • Я заметил, что если я расшифрую файл из командной строки, используя openssl enc -d -blowfish -a -in encrypted.txt, приглашение пароля помечается как 'bf-cbc', что предполагает Blowfish / CBC, а не Blowfish / ECB, однако, если я использую это, я получаю java.security.InvalidKeyException: Parameters missing исключение, но я не уверен, какой параметр я мог бы добавить.
  • Пароль, указанный в командной строке, должен быть каким-то образом преобразован, или getBytes("ASCII") неверен.
  • Требуется некоторая дополнительная обработка в коде Java для соли.

Ответы [ 2 ]

3 голосов
/ 12 декабря 2011

После долгих поисков я наткнулся на not-Пока-commons-ssl , который, кажется, обеспечивает метод для этого ...

byte[] decrypted = OpenSSL.decrypt("blowfish", password.toCharArray(), base64EncryptedBytes);

Когда я получаю некоторыераз я покопаюсь в их коде и выясню, что конкретно делается.В то же время это выглядит так: OpenSSL.java - это место для старта.

1 голос
/ 12 декабря 2011

openssl не использует пароль «секретно» напрямую, но использует его для получения ключа, поэтому вам нужно повторить вывод ключа в Java . Если вы используете параметр -p с openssl:

$ openssl enc -blowfish -a -salt -in original.txt  -pass pass:secret -p
salt=FB92391C90CF0EA5
key=C8B918619B0736F95704AD3BD53849EC
iv =6F92FB39C5795434
U2FsdGVkX1/7kjkckM8OpYRWgmNmYzHi8JWYOYpDK5w=

вы увидите, как она выводит соль (закодированную в шестнадцатеричном формате), а также вектор инициализации. Соль обычно передается на PBEKeySpec при генерации ключа, например

KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 1, 128);

Вектор инициализации предоставляется при инициализации шифра:

blowfishCipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));

который является отсутствующим параметром, на который вы ссылаетесь.

К сожалению, я не знаю, какую функцию вывода ключей openssl использует в этом случае или же тот же алгоритм поддерживается непосредственно в Java. Надеюсь, кто-то еще может предоставить эту информацию. Хороший эквивалентный пример использования AES можно найти в ответе на этот вопрос .

При более внимательном рассмотрении зашифрованной строки в вышеприведенном выводе, а именно: "U2FsdGVkX1 / 7kjkckM8OpYRWgmNmYzHi8JWYOYpDK5w =", если вы декодируете это base64, а затем шифруете его, вы получите:

Encrypted bytes: 
0000: 53 61 6C 74 65 64 5F 5F   FB 92 39 1C 90 CF 0E A5  Salted__..9.....
0010: 84 56 82 63 66 63 31 E2   F0 95 98 39 8A 43 2B 9C  .V.cfc1....9.C+.

Итак, строка "Salted__" плюс соль добавлены. Другими словами, вам также необходимо выяснить, как openssl форматирует закодированную строку, чтобы вы могли успешно извлечь соль и правильный шифротекст.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...