Как я могу преобразовать эту расшифровку Java Blowfish в Python? - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть некоторый код Java, который принимает зашифрованную строку, передает ее через функцию "hex_decode", а затем дешифрует ее с помощью Blowfish (CBC).Мне нужно взять этот код и преобразовать его в python, но я совершенно растерялся, особенно в том, что делает шестнадцатеричное декодирование Java.

Я смотрел документы здесь: https://pycryptodome.readthedocs.io/en/latest/src/cipher/classic.html#cbc-mode

Вот код Java.Обратите внимание, что значения составлены здесь, но представляют, как выглядят реальные значения.

public static int charToByte(final char c) {
        if (c >= '0' && c <= '9') {
            return (c - ZERO_BASE);
        } else if (c >= 'A' && c <= 'F') {
            return (c - ALPHA_BASE);
        } else if (c >= 'a' && c <= 'f') {
            return (c - LC_ALPHA_BASE);
        } else {
            throw new IllegalArgumentException("Illegal Hex character encountered '" + c + "'.");
        }
    }

    public static byte[] hex_decode(final String hexString) {
        // The string must be of even length or else the character-encoded
        // string does not
        // represent a valid byte array.
        if (hexString.length() % 2 != 0) {
            throw new IllegalArgumentException("Character encoded string is invalid because it is not of even length.");
        }

        int length = hexString.length() / 2;
        byte[] bytes = new byte[length];
        char[] chars = hexString.toCharArray();

        for (int i = 0; i < length; i++) {
            int j = i * 2;
            // Converting the character pair into the appropriate byte value.
            int high = charToByte(chars[j]);
            int low = charToByte(chars[j + 1]);

            int high4shift = (high << 4);
            int bitwiseresult = (high4shift | low);
            byte finalByte = (byte) bitwiseresult;
            bytes[i] = finalByte;
        }
        return bytes;
    }

    private byte[] decrypt(final byte[] value, final byte[] iv) {
        final Cipher cipher = CryptoProvider.getInstance().getBlowfishCipher();
        final IvParameterSpec ivSpec = new IvParameterSpec(iv);

        try {
            cipher.init(Cipher.DECRYPT_MODE, this.key, ivSpec);
        } catch (final InvalidKeyException e) {
            throw new SecurityException(e.getMessage());
        } catch (final InvalidAlgorithmParameterException e) {
            throw new SecurityException(e.getMessage());
        }

        try {
            return cipher.doFinal(value);
        } catch (final IllegalStateException e) {
            throw new SecurityException(e.getMessage());
        } catch (final IllegalBlockSizeException e) {
            throw new SecurityException(e.getMessage());
        } catch (final BadPaddingException e) {
            throw e;
        }
    }

    @Test
    public void decode_encryptedrequest() {

        String encryptedMessage = "BC49580BDE2F0DC5628C29F1F1DA02A3A159799B589DCD2EC74742E972A4AFCB9D54B264AE8D8F6200274E5C542FD5B242993EFDB47727276E617CDCE9D7DD9C26F31B1622F147DF2628584CC7BBDCDE8ECC52BE711A5767FE5E42109682496359DCBD9533D174C2D76BD6DB4EFC2CA55E1C1E18AEBD9C59E52CA6EEEC9307A8E64386F97EB0EFBBE6AEF08802066F634C2984D40E7950FF9EF005444622F120B691F1C3F50EF1DF209DFBED9580852DE5A5ED5BA964FA3D06432E9FEF1AB4069B67DE60FD6A9161946D43ED39D33C4D0D0717CAC29C5AC6B862A3F2784434D103EF6AFDD9630EA3399732A308F1749585F0357CF994C581D8934DC51EA83ADC26910D8F20373C5E3A7D46F54406855C0B2C2FDA79CD1FDC";
        String expiry = "0000016A06A1C776";

        final byte[] bytes = decrypt(hex_decode(encryptedMessage), hex_decode(expiry));

        System.out.println(new String(bytes, "ASCII"));

    }

В коде Java в качестве IV используется шестнадцатеричное декодированное поле «expiry».

IЯ просто не понимаю, что делает hex_decode, и как я могу перевести это на Python.Я вижу, что в python есть функция string.decode ('hex'), но, возможно, это не охватывает то, что делает функция java?Если нет, то как бы я его воссоздал?

Моя попытка такова:

def get_key():
    # This is a 128-bit BlowFish key, this is an example
    return b'13c43f0e15ed0fe2ae38fda9274daf0e'

def decrypt():

    encryptedMessage = 'BC49580BDE2F0DC5628C29F1F1DA02A3A159799B589DCD2EC74742E972A4AFCB9D54B264AE8D8F6200274E5C542FD5B242993EFDB47727276E617CDCE9D7DD9C26F31B1622F147DF2628584CC7BBDCDE8ECC52BE711A5767FE5E42109682496359DCBD9533D174C2D76BD6DB4EFC2CA55E1C1E18AEBD9C59E52CA6EEEC9307A8E64386F97EB0EFBBE6AEF08802066F634C2984D40E7950FF9EF005444622F120B691F1C3F50EF1DF209DFBED9580852DE5A5ED5BA964FA3D06432E9FEF1AB4069B67DE60FD6A9161946D43ED39D33C4D0D0717CAC29C5AC6B862A3F2784434D103EF6AFDD9630EA3399732A308F1749585F0357CF994C581D8934DC51EA83ADC26910D8F20373C5E3A7D46F54406855C0B2C2FDA79CD1FDC'
    expiry = '0000016A06A1C776'

    bs = Blowfish.block_size
    key = get_key()
    ciphertext = encryptedMessage.decode('hex')
    iv = expiry.decode('hex')

    cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
    msg = cipher.decrypt(ciphertext)

    print('msg: ' + msg)
    last_byte = msg[-1]
    msg = msg[:- (last_byte if type(last_byte) is int else ord(last_byte))]
    print('repr(msg): ' + repr(msg))
    print('ascii: ' + repr(msg).decode('ascii'))


decrypt()

Я ожидаю строку в формате Legibile, но в Python я получаю что-то вроде

ascii: : '\xc7\x1f\xddT\xcf:\x0fOA\xc7\xc7X\x91Y\xb4M\xbd\x90o\xb4T9\ etc etc etc
...