I'd probably avoid doing this, but you should find:
will do what you want. It would be better if ECB was NONE but the
provider won't recognise that. ECB for a block cipher is essentially
NONE (i.e. don't modify the mode of whatever engine I've asked for).
I'm aware of. You'd be better to map the OID to the transform you want
explicitly. I think I can understand why you're trying to do this, the
an exercise to the reader. So there's nothing wrong with the idea, we
simplifies operations with standards like CMS.
Post by Daniil IvanovHi,
What I originally wanted to do was to use OID + NoPadding.
Provider provider = new BouncyCastleProvider();
Service service = provider.getService("Cipher", "2.16.840.1.101.3.4.1.2");
System.out.println(service.toString());
BC: Cipher.AES -> org.bouncycastle.jcajce.provider.symmetric.AES$ECB
aliases: [2.16.840.1.101.3.4.2, 2.16.840.1.101.3.4.22,
2.16.840.1.101.3.4.42]
First alias is a SHA2 branch OID and second and third are not defined
anywhere.
Thanks, Daniil
On Fri, Jul 18, 2014 at 5:10 PM, Daniil Ivanov
Hi Tim!
I'm using BouncyCastle 1.50 and JDK 1.7. I did the following
/* This test fails - second block of recovered text is
corrupted */
@Test
public void testCBC() throws Exception {
BouncyCastleProvider provider = new BouncyCastleProvider();
SecureRandom random = new SecureRandom();
Cipher cipher =
Cipher.getInstance("2.16.840.1.101.3.4.1.2/CBC/NoPadding", provider);
byte[] symmetricKey = new byte[cipher.getBlockSize()];
random.nextBytes(symmetricKey);
byte[] data = new byte[2 * cipher.getBlockSize()];
random.nextBytes(data);
byte[] iv = new byte[cipher.getBlockSize()]; // {0} IV
AlgorithmParameterSpec algoSpec = new IvParameterSpec(iv);
SecretKeySpec secretKey = new SecretKeySpec(symmetricKey, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, algoSpec);
byte[] encryptedData = cipher.doFinal(data);
Cipher cipher2 = Cipher.getInstance("AES/CBC/NoPadding", provider);
cipher2.init(Cipher.DECRYPT_MODE, secretKey, algoSpec);
byte[] decryptedData = cipher2.doFinal(encryptedData);
assertEquals(DatatypeConverter.printHexBinary(data),
DatatypeConverter.printHexBinary(decryptedData));
}
/* This test succeeds */
@Test
public void testECB() throws Exception {
BouncyCastleProvider provider = new BouncyCastleProvider();
SecureRandom random = new SecureRandom();
Cipher cipher =
Cipher.getInstance("2.16.840.1.101.3.4.1.2/CBC/NoPadding", provider);
byte[] symmetricKey = new byte[cipher.getBlockSize()];
random.nextBytes(symmetricKey);
byte[] data = new byte[2 * cipher.getBlockSize()];
random.nextBytes(data);
byte[] iv = new byte[cipher.getBlockSize()]; // {0} IV
AlgorithmParameterSpec algoSpec = new IvParameterSpec(iv);
SecretKeySpec secretKey = new SecretKeySpec(symmetricKey, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, algoSpec);
byte[] encryptedData = cipher.doFinal(data);
Cipher cipher2 = Cipher.getInstance("AES/ECB/NoPadding", provider);
AlgorithmParameterSpec algoSpec2 = null;
cipher2.init(Cipher.DECRYPT_MODE, secretKey, algoSpec2);
byte[] decryptedData = cipher2.doFinal(encryptedData);
assertEquals(DatatypeConverter.printHexBinary(data),
DatatypeConverter.printHexBinary(decryptedData));
}
So cipher definitely uses ECB chaining mode for me. Which BC
and JDK do you use?
Thanks, Daniil
On Fri, Jul 18, 2014 at 11:59 AM, Tim Whittington
I'll be honest, I'm not really sure eitherâŠ
This is a quirk of the way BaseBlockCipher works (helped I
guess by the general BlockCipher vs mode vs padding confusion).
BaseBlockCipher
-> BufferedGenericBlockCipher
-> PaddedBufferedBlockCipher
-> CBCBlockCipher
+ PKCS7Padding
setMode(âCBCâ) replaces that with the same construction (a noop).
BaseBlockCipher
-> BufferedGenericBlockCipher
-> BufferedBlockCipher
-> CBCBlockCipher
⊠which isnât ECB (Iâve tested, and itâs definitely still
doing CBC), but will complain about invalid data lengths if
the input isnât block aligned.
What will happen internally is the JCE will find the OID
implementation, then call engineSetMode and engineSetPadding -
the base engine will already have CBC mode on it so XOR'ing
the IV twice will remove it (that probably explains the ECB).
The provider should probably through an exception in the
second case - the OIDs fully describe the algorithm, mode, and
padding. From that point of view the second usage doesn't
really make sense.
Yeah. Perhaps it'd make more sense if AES$CBC et al specified
cipher/mode/padding rather than providing a
CBCBlockCipher+relying on the BufferedGenericBlockCipher
constructor magic padding assumption, and then BaseBlockCipher
errors if the mode/padding is additionally specified?
tim
Post by Daniil IvanovHi,
I'm puzzled with how I can use OID and cipher parameters
in Cipher.getInstance.
Post by Daniil IvanovCipher.getInstance("2.16.840.1.101.3.4.1.2", "BC");
This call returns AES with CBC and PKCS#7 padding.
Cipher.getInstance("2.16.840.1.101.3.4.1.2/CBC/NoPadding",
"BC");
Post by Daniil IvanovThis call return AES with ECB and NoPadding.
I don't quite get how this end up doing ECB.
Any ideas?
Thanks, Daniil