iOS app中经常使用CCCrypt函数对重要数据进行加解密。在对某app进行安全分析时,遇到使用CCCrypt函数对某请求参数进行AES128加密及解密,使用kCCOptionPKCS7Padding | kCCOptionECBMode模式。
因此,这里对AES128加密算法进行还原(解密算法类似),分别有Objective-C及java,附上代码如下:
Objective-C:
+(NSString *)AES128Encrypt:(id)plainText key:(id)key
{
char keyPtr[kCCKeySizeAES128+1];
memset(keyPtr, 0, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
//NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
//NSLog(@"data is: %@",data);
NSUInteger dataLength = [plainText length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
//kCCOptionECBMode
//3
NSLog(@"value is: %d",kCCOptionPKCS7Padding | kCCOptionECBMode);
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr,
kCCBlockSizeAES128,
NULL,
[plainText bytes],
dataLength,
buffer,
bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
return [self hexStringFromData:resultData];
}
free(buffer);
return nil;
}
java:
private static final String algorithm = "AES/ECB/PKCS7Padding";
static {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
private static String encrypt(byte[] plainText,byte[] keyBytes) {
String result = "";
try {
Key key = generateKey(keyBytes);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptBytes = cipher.doFinal(plainText);
result = bytesToHexString(encryptBytes);
result = result.toUpperCase();
}catch(Exception e) {
e.printStackTrace();
}
return result;
}
private static Key generateKey(byte[] keyBytes) {
Key key = new SecretKeySpec(keyBytes,"AES");
return key;
}
补充CCCrypt函数说明:
调用CCCrypt函数时,需要引入框架
#import
CCCrypt函数定义:
CCCryptorStatus CCCrypt(
CCOperation op, /* kCCEncrypt, etc. */
CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */
CCOptions options, /* kCCOptionPKCS7Padding, etc. */
const void *key,
size_t keyLength,
const void *iv, /* optional initialization vector */
const void *dataIn, /* optional per op and alg */
size_t dataInLength,
void *dataOut, /* data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved)
参数说明:
CCOperation op, // kCCEncrypt(数值0,表示加密)、kCCDecrypt(数值1,表示解密)
CCAlgorithm alg,
/*
kCCAlgorithmAES128=0,
kCCAlgorithmAES=0,
kCCAlgorithmDES=1,
kCCAlgorithm3DES=2,
kCCAlgorithmCAST,
kCCAlgorithmRC4,
kCCAlgorithmRC2,
kCCAlgorithmBlowfish
*/
//表示选择哪个算法标准进行加解密,如上面使用的kCCAlgorithmAES128
CCOptions options,
/*
kCCModeECB = 1,
kCCModeCBC = 2,
kCCModeCFB = 3,
kCCModeCTR = 4,
kCCModeF8 = 5, // Unimplemented for now (not included)
kCCModeLRW = 6, // Unimplemented for now (not included)
kCCModeOFB = 7,
kCCModeXTS = 8,
kCCModeRC4 = 9,
kCCModeCFB8 = 10
*/
//表示选择的加解密模式
const void *key, //密钥,对称加密,加解密的密钥都一样,依据选择的算法标准,密钥长度不同
size_t keyLength,//密钥长度,加解密时依据keyLength取密钥的长度
/*
kCCKeySizeAES128 = 16,
kCCKeySizeAES192 = 24,
kCCKeySizeAES256 = 32,
kCCKeySizeDES = 8,
kCCKeySize3DES = 24,
kCCKeySizeMinCAST = 5,
kCCKeySizeMaxCAST = 16,
kCCKeySizeMinRC4 = 1,
kCCKeySizeMaxRC4 = 512,
kCCKeySizeMinRC2 = 1,
kCCKeySizeMaxRC2 = 128,
kCCKeySizeMinBlowfish = 8,
kCCKeySizeMaxBlowfish = 56,
*/
const void *iv, //偏移向量
const void *dataIn, //进行加解密的原始数据
size_t dataInLength,//进行加解密的原始数据的长度
void *dataOut, //加解密完后,数据保存的地方
size_t dataOutAvailable, //保存加解密后的数据需要的空间
size_t *dataOutMoved //保存数据后,写入的数据的具体长度