在我的iOS应用中,我必须解密来自服务器的数据。我使用CommonCrypto框架,经过几次试验,我成功解密了

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

在Java服务器中,数据使用
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);

现在,我不了解kCCOptionPKCS7Padding | kCCModeCBC的含义。 kCCOptionPKCS7Padding = 0x0001kCCModeCBC = 2,所以kCCOptionPKCS7Padding | kCCModeCBC = 3但不存在值3的分组密码的选项。

有没有人可以帮助我理解?

最佳答案

您在此处使用的kCCModeCBC不正确。所有CCOption枚举值都以kCCOption开头。 kCCModeCBCCCMode枚举的一部分。您无法通过这种方式将它们组合在一起。您正在摆脱它,因为CBC恰好是默认值。您应该删除| kCCModeCBC。 (CCMode由名为CCCryptorCreateWithMode的较新接口使用。您使用的接口默认为CBC,并且可以选择切换到ECB模式。)

对于您更深层次的问题,这些是bit fields。因此,“位零”(值为1)是PKCS7填充。第一位(值为2)打开ECB(不是CBC)。如果“或”它们(与添加它们相同),则得到3,这意味着两个选项。这是在C中传递布尔数据的一种极为常见的方法,即为每个字段赋予一个较大整数的一位。

如果有更多字段,则它们的值将为4、8、16、32等。所有的2的幂。因此,您打开或关闭的选项恰好是二进制数,分别为1(打开)和0(关闭)。

C没有很好的方法来维护这些类型的值的类型安全,因此它不会阻止您像在此所做的那样组合无关的枚举。

它可以与kCCModeCBC一起工作的原因是它与kCCOptionECBMode具有相同的值。您的加密处于ECB模式,而不是CBC模式。 (这恰好意味着您的密码几乎绝对不安全,但这是一个单独的问题。)

10-07 12:38