Different wrap value in bcprov-jdk18on 1.78.1 with input <= 8 characters
Hi,
We have a problem since an update of bcprov when wrapping a string <= 8 characters. The wrap value is different:
Our code
import java.nio.charset.StandardCharsets;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESWrapEngine;
import org.bouncycastle.crypto.params.KeyParameter;
public class TestRFC3394 {
public static void main(String[] args) throws InvalidCipherTextException {
String secret = "toto1234";
System.out.println("secret: " + secret);
String key = "34B6E58B090922C15641EE98183682F5";
AESWrapEngine aes = new AESWrapEngine();
KeyParameter keyparam = new KeyParameter(key.getBytes(StandardCharsets.UTF_8));
aes.init(true, keyparam);
byte[] encryptedString = aes.wrap(secret.getBytes(StandardCharsets.UTF_8), 0, 8);
String wrappedString = new String(Hex.encodeHex(encryptedString));
System.out.println("wrapped: " + wrappedString);
aes.init(false, keyparam);
byte[] unwrappedString = aes.unwrap(encryptedString, 0, encryptedString.length);
System.out.println("unwrapped: " + new String(unwrappedString));
}
}
With bcprov-jdk15on, here is the output:
secret: toto1234
wrapped: b9f7a272d8cecf28a27b724d5a75d83e
unwrapped: toto1234
With bcprov-jdk18on 1.78.1:
secret: toto1234
wrapped: 48ad8cbfc3dd53aec3a45c78b2d3fc88
unwrapped: toto1234
We have made test with a Rust code to check the output and we have the same output as bcprov-jdk15on:
use aes_kw::Kek;
use anyhow::*;
fn main() -> anyhow::Result<()> {
let secret = "toto1234";
println!("secret: {}", secret);
let key_bytes = "34B6E58B090922C15641EE98183682F5".as_bytes();
let mut k32 = [0u8; 32];
k32.copy_from_slice(&key_bytes);
let kek = Kek::from(k32);
let mut out = vec![0; 16];
let _ = kek.wrap(&secret.as_bytes(), &mut out);
println!("wrapped: {}", hex::encode(&out));
let mut out2 = vec![0; 8];
let _ = kek.unwrap(&out, &mut out2);
println!("unwrapped: {}", String::from_utf8(out2)?);
Ok(())
}
secret: toto1234
wrapped: b9f7a272d8cecf28a27b724d5a75d83e
unwrapped: toto1234
Why do we have a different wrap value ? It's a problem when two applications is using the value with different version of bcprov.
Regards
Any idea about this issue?
Presumably this commit: https://github.com/bcgit/bc-java/commit/b11c2442b01c2a638dbcbfe6eabbc7947897bdc5 ? That would have landed in version 1.73. Could you clarify what the original version you were using was?
As I recall this was made for compatibility with other implementations, although I believe there is a fair amount of disagreement and/or misunderstanding about what the spec actually says for small keys.
Yes, it is most certainly from this commit. In the "1-block" case, the code was running 6 passes before (same as long wrapped value), but only 1 after, resulting in different output with the next version.
The only other implementation i tried was the rust one described above, which complies with the original code (6 passes in all cases). And the real problem for us is compatibility between multiple servers using different versions of BC.