我正在尝试将BouncyCastle的Java实现中的AES加密与Ruby匹配。不知何故,即使使用相同的键,IV和有效负载,我似乎在两种语言中也无法获得相同的结果。
在此示例中,我使用ruby生成密钥和IV,然后在Java代码中重用此密钥和IV。
任何人都可以发现问题所在吗?
这是红宝石代码:
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一起使用的方法。
我很干。这里有什么主意吗?
答案 0 :(得分:1)
因此,正如詹姆斯指出的那样,红宝石的块大小不正确。对于CFB,我应该使用8位块大小,但是应该使用默认的128位。
这解决了它:
cipher = OpenSSL::Cipher.new("AES-128-CFB8")