iOS逆向之还原CCCrypt加解密算法

原创
2019/12/04 00:00
阅读数 438

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 <CommonCrypto/CommonCryptor.h>


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


本文分享自微信公众号 - 网络安全技术点滴分享(gh_c85d6ae14603)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
这个padding的表就是错的
01/10 14:25
回复
举报
更多评论
打赏
1 评论
0 收藏
0
分享
返回顶部
顶部