在我的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 = 0x0001
和kCCModeCBC = 2
,所以kCCOptionPKCS7Padding | kCCModeCBC = 3
但不存在值3
的分组密码的选项。有没有人可以帮助我理解?
最佳答案
您在此处使用的kCCModeCBC
不正确。所有CCOption
枚举值都以kCCOption
开头。 kCCModeCBC
是CCMode
枚举的一部分。您无法通过这种方式将它们组合在一起。您正在摆脱它,因为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模式。 (这恰好意味着您的密码几乎绝对不安全,但这是一个单独的问题。)