Я пытаюсь сопоставить шифрование AES с java-реализацией BouncyCastle с Ruby. Так или иначе, даже с тем же ключом, IV и полезной нагрузкой, я не могу получить одинаковые результаты на обоих языках.
В этом примере я использую ruby для генерации ключа и IV, а затем повторно использую этот ключ и IV в Java-коде.
Может ли кто-нибудь определить, что случилось?
Здесь код ruby:
require 'openssl'
cipher = OpenSSL::Cipher::AES.new(128, "CFB")
cipher.encrypt
payload = "\x01\x02\x03\x04".b
puts "key"
puts cipher.random_key.unpack("H*")
puts "iv"
puts cipher.random_iv.unpack("H*")
puts (cipher.update(payload) + cipher.final).unpack("H*")
И его выход:
key
19900205760f9b9696b34cacdbf0189d
iv
b549f3bb806c4bce9c949f61185f2c38
303dc6e6
И (не такой) соответствующий java-код
byte[] key = hexStringToByteArray("19900205760f9b9696b34cacdbf0189d");
byte[] iv = hexStringToByteArray("b549f3bb806c4bce9c949f61185f2c38");
byte[] payload = new byte[] { 1, 2, 3, 4};
AESEngine aesEngine = new AESEngine();
CFBBlockCipher cipher = new CFBBlockCipher(aesEngine, 8);
ParametersWithIV params = new ParametersWithIV(new KeyParameter(key), iv);
BufferedBlockCipher bbc = new BufferedBlockCipher(cipher);
bbc.init(true, params);
byte[] output = new byte[payload.length];
int result = bbc.processBytes(payload, 0, payload.length, output, 0);
bbc.doFinal(output, result);
System.out.println("With BC: " + bytesToHex(output));
Результат java
305F1C09
Для любой полезной нагрузки первый байт всегда совпадает с обеими реализациями, но тогда остальное варьируется. Может ли быть так, что цикл обратной связи шифрования работает не так?
Изменение: Как отметил Джеймс в комментариях, это проблема размера блока. В приведенном выше коде ruby, похоже, использует по умолчанию размер блока 128 бит, тогда как в java-коде используется 8-битовый блок. В моем случае я должен сопоставить код ruby с java, поэтому теперь мне нужно найти способ использования 8-битного размера блока с ruby.
Я сухая. Любая идея здесь?
Так, как указал Джеймс, размер блока был неправильным для рубина. Я должен использовать размер блока 8 бит для CFB, но вместо этого использовал 128 бит по умолчанию.
Это решило это:
cipher = OpenSSL::Cipher.new("AES-128-CFB8")