I have a confusing problem, where decrypting a file which was encrypted using CCCrypt\'s AES-CBC mode with a randomized, 16byte IV produces the exact same output whether I p
It's also worth pointing out that one should never include the mode with the padding options. I've seen this around quite a bit, and I've actually fallen into the same pitfall trying to be a "explicit as possible".
kCCOptionPKCS7Padding | kCCModeCBC
Should be:
kCCOptionPKCS7Padding
Fun fact 1: Both kCCModeEBC
and kCCOptionPKCS7Padding
share the same value: 1, and would actually evaluate to using kCCOptionPKCS7Padding
, which would then default to kCCModeCBC
.
Fun fact 2: Using kCCOptionPKCS7Padding | kCCModeCBC
evaluates to both kCCOptionPKCS7Padding
flag and kCCOptionECBMode
being set, which actually results in kCCModeEBC
being used.
Used for formatting comment.
With iv:
clear data: <4cd9b050 30c04bf9 2a0cb024 19010a31>
iv data: <724a7fc0 0d8ac9d5 f09ff4c1 64d2d1bb>
key data: <78656a1a 337fffffd6 fa52e34d 9156d187>
crypt data: <d2c2efee 54e43781 549eec03 9db688e1 7c4248e7 e2ac1d80 7105ffae 4043ffb3>
decrypt data: <4cd9b050 30c04bf9 2a0cb024 19010a31>
With iv of 0's:
clear data: <4cd9b050 30c04bf9 2a0cb024 19010a31>
iv data: <00000000 00000000 00000000 00000000>
key data: <78656a1a 337fffffd6 fa52e34d 9156d187>
crypt data: <cf85cdbe 10a87309 a6fb4c4e ce640619 6be7b155 9db3f066 97e461e7 ced7960f>
decrypt data: <4cd9b050 30c04bf9 2a0cb024 19010a31>
It is clear that the iv is not being used in the OP code.
Code for above:
CCCryptorStatus ccStatus = kCCSuccess;
size_t cryptBytes = 0;
NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];
ccStatus = CCCrypt( encryptOrDecrypt, // kCCEncrypt or kCCDecrypt
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
key.bytes,
kCCKeySizeAES128,
iv.bytes,
dataIn.bytes,
dataIn.length,
dataOut.mutableBytes,
dataOut.length,
&cryptBytes);
dataOut.length = cryptBytes;
You can read the correct answer here: http://www.remote-exploit.org/archives/2012/01/09/the_apple_idioten_vektor_iv/
Apple made an error in their Crypto Library that assumes that if the IV vector is not provided they automatically set the IV to a zero vector instead of returning an error. An IV should always be provided to ensure the best security and Apple should not be doing their zero assumption as it greatly weakens security and makes it vulnerable to attacks.
The iv is only used for the first block on decryption, further blocks use the cipher text from the previous block so it is somewhat self-synchronizing.
Wikipedia image:
From Wikipedia Block cipher mode of operation.
So, picking up decryption in the middle of a CBC encrypted stream on a block boundary works except for the first block.