In my iOS app I have to decrypt data coming from a server. I use CommonCrypto
framework and, after several trials, I successfully decrypted with
CCCrypt(kCCDecrypt, // operation
kCCAlgorithmAES128, // Algorithm
kCCOptionPKCS7Padding | kCCModeCBC, // options
key.bytes, // key
key.length, // keylength
nil,// iv
cipherData.bytes, // dataIn
cipherData.length, // dataInLength,
decryptedData.mutableBytes, // dataOut
decryptedData.length, // dataOutAvailable
&outLength); // dataOutMoved
In the java server the data is crypted with
byte[] buff = new byte[100];
byte[] buf2 = new byte[32];
byte[] mainKey = ...
byte[] raw = ...
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new AESEngine());
KeyParameter par = new KeyParameter(mainKey);
int minSize = cipher.getOutputSize(data.length);
byte[] outBuf = new byte[minSize];
int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
int length2 = cipher.doFinal(outBuf, length1);
int actualLength = length1 + length2;
byte[] result = new byte[actualLength];
System.arraycopy(outBuf, 0, result, 0, result.length);
Now, I don't understand the sense of kCCOptionPKCS7Padding | kCCModeCBC
. kCCOptionPKCS7Padding = 0x0001
and kCCModeCBC = 2
so kCCOptionPKCS7Padding | kCCModeCBC = 3
but not exist options for block ciphers with value 3
.
Is there someone that can help me to understand?
Your use of kCCModeCBC
here is incorrect. All CCOption
enum values begin with kCCOption
. kCCModeCBC
is part of the CCMode
enum. You can't combine them this way. You're getting away with it because CBC happens to be the default. You should remove | kCCModeCBC
. (CCMode
is used by a newer interface called CCCryptorCreateWithMode
. The interface you're using defaults to CBC and has an option to switch to ECB mode instead.))
To your deeper question, these are bit fields. So "bit zero" (which has a value of 1) is PKCS7 padding. Bit one (which has a value of 2) turns on ECB (not CBC). If you "or" them (which this the same as adding them), you get 3, which means both options. This is an extremely common way to pass boolean data in C, giving each field one bit in a larger integer.
If there were more fields, they would have values 4, 8, 16, 32, etc. All powers of two. So the options you turn on or off are exactly a binary number of ones (on) and zeros (off).
C does not have a really good way to maintain type safety for these kinds of values, so it won't stop you from combining unrelated enums like you've done here.
The reason it "works" with kCCModeCBC
is that it has the same value as kCCOptionECBMode
. Your encryption is in ECB mode, not CBC mode. (Which happens to mean that your cypher is almost certainly deeply insecure, but that's a separate issue.)