Проблемы с шифрованием/дешифрованием BlowFish (JBoss Encryption)

Вот проблема, с которой я столкнулся при шифровании/дешифровании BlowFish.

Приведенный ниже код используется для тестирования шифрования/дешифрования BlowFish.

// Code below omits comments for Brevity

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

import java.math.BigInteger;

public class JBoss {

    public static void main(String[] args) throws Exception {

        if ((args.length != 2)
                || !(args[0].equals("-e") | args[0].equals("-d"))) {
            System.out
                    .println("Usage:\n\tjava JBoss <-e|-d> <encrypted_password>");
            return;
        }

        String mode = args[0];

        byte[] kbytes = "jaas is the way".getBytes();
        SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");
        Cipher cipher = Cipher.getInstance("Blowfish");

        String out = null;

        if (mode.equals("-e")) {
            String secret = args[1];
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encoding = cipher.doFinal(secret.getBytes());
            out = new BigInteger(encoding).toString(16);
        } else {
            BigInteger secret = new BigInteger(args[1], 16);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] encoding = cipher.doFinal(secret.toByteArray());
            out = new String(encoding);
        }
        System.out.println(out);
    }
}

Теперь, если я попытаюсь зашифровать строку

u7mzqw2

Я получаю значение как

-7ccb7ff0c2858a

Если я попытаюсь расшифровать

-7ccb7ff0c2858a

Я получаю ошибку, как показано ниже:

    java JBoss -d -7ccb7ff0c2858a
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
        at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
        at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
        at com.sun.crypto.provider.BlowfishCipher.engineDoFinal(DashoA13*..)
        at javax.crypto.Cipher.doFinal(DashoA13*..)
        at JBoss.main(JBoss.java:41)

Весь код здесь

Если я не ошибаюсь, это не имеет ничего общего с исходным значением длиной 7 символов или зашифрованным значением без / 8 = 0, так как работает приведенное ниже.

java JBoss -e qwerty

-40e961f375c2eee6

Java JBoss -d -40e961f375c2eee6

qwerty

Что мне не хватает??


person Abhilash    schedule 23.01.2013    source источник
comment
Почему вы переходите на BigInteger?   -  person CodesInChaos    schedule 23.01.2013
comment
Это трюк, чтобы получить шестнадцатеричные строки, это сложно в том смысле, что bigints подписаны, и это, конечно, далеко от идеала.   -  person Maarten Bodewes    schedule 23.01.2013
comment
Не то чтобы я этого хотел, похоже, именно так реализована реализация в JBoss. См. эту ссылку (usefulfor.com/security/2009/ 24.09.)   -  person Abhilash    schedule 23.01.2013


Ответы (3)


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

Ввод: asdfda

16::10

60::3c

105::69

57::39

-60::-3c

110::6e

19::13

-52::-34

Закодированное значение: 103c6939c46e13cc

Как вы можете видеть, элементы слева — это байты, а справа у нас есть отдельные большие целые числа со значениями по основанию 16, а внизу у нас есть закодированное значение. Вы можете увидеть большое совпадение с образцом. кроме значений с -tive. например -60 соответствует значению -3c , но так как при преобразовании 1 байта значение становится c4 (см. себя).

Теперь я протестировал значение для шифрования как u7mzqw2, посмотрим, что произойдет.

Ввод: u7mzqw2

-1::-1

-125::-7d

52::34

-128::-80

15::f

61::3d

122::7a

118::76

Закодированное значение: -7ccb7ff0c2858a

Теперь вы видите сопоставление с образцом, теперь нет, почему бы и нет? давайте посмотрим, хорошо -1 чье шестнадцатеричное должно быть -1 ? ??? , нет, это 0XFF, теперь мы можем представить 0xFF в байтах? Нет, мы не можем. прочитайте сами Byte и -1

Обновление: что меня озадачило, так это то, как эти кодировки оценивались? Все еще ищу, помогите мне определить это

person Abhiram mishra    schedule 23.01.2013
comment
Извлеченный урок: всякий раз, когда вы получаете зашифрованную строку, убедитесь, что ваша логика дешифрования обработает правильный ответ, не предполагайте :):) - person Abhilash; 25.01.2013
comment
Я преобразовывал строку в базу 64 с помощью класса java.security.MessageDigest, он иногда пропускал 1 символ при предоставлении выходной строки, поэтому в этом методе может быть какая-то ошибка. Теперь я изменил метод, теперь он работает нормально. Шифрование и дешифрование - сложные вещи. - person Maveňツ; 28.02.2014

Попробуй это,

public static void main(String[] args) throws Exception {
     // generate key
     KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish");
     SecretKey secretKey = keyGen.generateKey();
     // get Cipher and init it for encryption
     Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
     cipher.init(Cipher.ENCRYPT_MODE, secretKey);
     String data="u7mzqw2";

     // encrypt data
     byte[] cipherText = cipher.doFinal(data.getBytes());
     // get the initialization vector from the cipher
     byte[] ivBytes = cipher.getIV();
     IvParameterSpec iv = new IvParameterSpec(ivBytes);

     byte[] keyBytes = secretKey.getEncoded();
     // create a SecretKeySpec from key material
     SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "Blowfish");
     // get Cipher and init it for encryption
     cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
     cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv);
     byte[] plainText = cipher.doFinal(cipherText);
     System.out.println(new String(plainText));
}
person mak    schedule 23.01.2013
comment
Я не думаю, что у OP есть возможность изменить код, предоставленный источник является реализацией по умолчанию, предоставленной Jboss. - person Johnbabu Koppolu; 23.01.2013

Если мы посмотрим на наш код, следующая строка в secret.toByteArray() дает массив длиной 7 байтов, который должен быть причиной проблемы.

byte[] encoding = cipher.doFinal(secret.toByteArray()); //During decoding logic

Проблемы, похоже, связаны с реализацией BlowfishCipher. , ШифрКор.

public BlowfishCipher()
{
        core = new CipherCore(new BlowfishCrypt(),
                              BlowfishConstants.BLOWFISH_BLOCK_SIZE);
}

http://www.docjar.com/html/api/com/sun/crypto/provider/BlowfishConstants.java.html

Мы используем BlowfishConstants.BLOWFISH_BLOCK_SIZE = 8; // количество байтов

http://hg.openjdk.java.net/jdk6/jdk6/jdk/raw-file/2d585507a41b/src/share/classes/com/sun/crypto/provider/CipherCore.java

if ((paddingLen > 0) && (paddingLen != blockSize) &&
            (padding != null) && decrypting) {
            throw new IllegalBlockSizeException
                ("Input length must be multiple of " + blockSize +
                 "when decrypting with padded cipher");
        }
person n09    schedule 23.01.2013
comment
С BlowfishCipher проблем нет, шифр дает зашифрованный массив байтов, размер которого всегда кратен 8, исходный массив байтов зашифровывается, когда BigInteger используется для преобразования его в шестнадцатеричную строку и наоборот. - person Johnbabu Koppolu; 24.01.2013
comment
Примечание. Во время шифрования, а также при расшифровке мы видим массив байтов длиной 7 для пароля «u7mzqw2», поэтому проблема заключается в том, что шифрование работает там, где не удается расшифровать. - person n09; 30.01.2013
comment
извините при шифровании мы видим массив длиной 8 байт - person n09; 30.01.2013