iOS逆向之还原CCCrypt加解密(AES128Encrypt)

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 //保存数据后,写入的数据的具体长度

你可能感兴趣的:(iOS逆向之还原CCCrypt加解密(AES128Encrypt))