Шифрование Blowfish GoLang и расшифровка Java

Невозможно расшифровать зашифрованный текст на Java, который зашифрован в GoLang с помощью Blowfish.

Шифрование

import (
    "testing"
    "golang.org/x/crypto/blowfish"
    "github.com/andreburgaud/crypt2go/ecb"
    "github.com/andreburgaud/crypt2go/padding"
    "fmt"
    "encoding/base64"
)

func TestEncrypt(t *testing.T) {

    bytes := []byte("cap")
    key := []byte("1c157d26e2db9a96a556e7614e1fbe36")

    encByte := encrypt(bytes, key)
    enc := base64.StdEncoding.EncodeToString(encByte)
    fmt.Printf("ENC - %s\n", enc)
}

func encrypt(pt, key []byte) []byte {
    block, err := blowfish.NewCipher(key)
    if err != nil {
        panic(err.Error())
    }
    mode := ecb.NewECBEncrypter(block)
    padder := padding.NewPkcs5Padding()
    pt, err = padder.Pad(pt) // padd last block of plaintext if block size less than block cipher size
    if err != nil {
        panic(err.Error())
    }
    ct := make([]byte, len(pt))
    mode.CryptBlocks(ct, pt)
    return ct
}

// Output
// ENC - AP9atM49v8o=

Расшифровка

import lombok.SneakyThrows;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import static java.util.Base64.getDecoder;
import static java.util.Base64.getEncoder;

public class UserAuthenticationFilter {

    public static void main(String[] args) throws Exception {
        String key = "1c157d26e2db9a96a556e7614e1fbe36";
        System.out.println(decrypt(getDecoder().decode("AP9atM49v8o = "), key));

        // encryption and decryption verification
        // String plainText = "cap";
        // String cipher = encrypt(plainText, key);
        // String decrypted = decrypt(getDecoder().decode(enc), key);
        // assert decrypted.equals(plainText);
    }

    @SneakyThrows
    public static String encrypt(String plainText, String key) {
        byte[] myKeyByte = hexToBytes(key);
        SecretKeySpec skeySpec = new SecretKeySpec(myKeyByte, "Blowfish");
        Cipher ecipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
        ecipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        byte[] src = ecipher.doFinal(plainText.getBytes("ISO-8859-1"));
        return getEncoder().encodeToString(src);
    }

    @SneakyThrows
    public static String decrypt(byte[] cipherContent, String key) {
        byte[] myKeyByte = hexToBytes(key);
        SecretKeySpec skeySpec = new SecretKeySpec(myKeyByte, "Blowfish");
        Cipher dcipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
        dcipher.init(2, skeySpec);
        byte[] dcontent = dcipher.doFinal(cipherContent);
        return (new String(dcontent, "ISO-8859-1")).trim();
    }

    private static byte[] hexToBytes(String str) {
        if (str == null) {
            return null;
        } else if (str.length() < 2) {
            return null;
        } else {
            int len = str.length() / 2;
            byte[] buffer = new byte[len];

            for(int i = 0; i < len; ++i) {
                buffer[i] = (byte)Integer.parseInt(str.substring(i * 2, i * 2 + 2), 16);
            }

            return buffer;
        }
    }

}

// Output
// BY x³

Судя по выходным данным, шифрование в GoLang и дешифрование в Java не создают одинаковый простой текст. Первоначально предполагалось, что проблема может быть связана с байтом голанга (от 0 до 255) и байтом java (от -128 до 127), участвующим в кодировании и декодировании base64. Но копаясь в коде расшифровки Java, он корректно обрабатывается с помощью value & 255.

Расшифровка одного и того же зашифрованного текста в голанге работает отлично. Также отлично работает шифрование и дешифрование в Java. Но не шифрование в одном, а дешифрование в другом.

Я считаю, что логика шифрования и дешифрования была правильной. Только догадываюсь, может быть, есть какой-то конкретный язык ??? отсутствует при переносе зашифрованного текста на другой язык для расшифровки.

При расшифровке вы не указываете заполнение, а при шифровании вы используете заполнение.

Michael 16.07.2018 09:24

@Michael. Для тестирования как шифрования, так и дешифрования на Java я использую Blowfish/ECB/PKCS5Padding для шифрования и Blowfish/ECB/NoPadding для дешифрования, которое работает должным образом. Так что я думаю, что если с прокладкой проблема, то она уже плюнула на BadPaddingException.

The Coder 16.07.2018 09:33

Отредактируйте информацию в вопросе, пожалуйста

Michael 16.07.2018 09:36

Я считаю, что ваша проблема в bytes из примера th golang. Я не специалист по голангу, но предполагаю, что вы создаете массив байтов из строковых символов, а не декодируете шестнадцатеричное значение.

gusto2 16.07.2018 09:39

@ gusto2 gotcha ..! Проблема заключается в преобразовании ключа в byte [], вместо того, чтобы декодировать шестнадцатеричный код, а просто преобразовать его в байт. Вы можете опубликовать это как ответ.

The Coder 16.07.2018 09:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
5
987
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
key := []byte("1c157d26e2db9a96a556e7614e1fbe36")

Я считаю, что этот фрагмент кода возвращает байтовый массив самой строки, а не шестнадцатеричное декодированное значение. Чтобы получить действующий ключ, вы можете попробовать использовать шестнадцатеричное декодирование

Другие вопросы по теме