У меня есть некоторый код 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