每个iOS开发都需要学会使用Hopper之困惑我许久的:不同的分类写相同的方法哪个被执行,哪个不被执行导致出现问题

问题是我的分类方法没被执行。

其实标题应该是:由相同的加密算法但使用了不同的填充算法引发的血案

我写的分类里的代码


@implementation NSData (YYYYY)

- (NSData *)YYY_AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv

{

    return [self YYY_AES128Operation:kCCEncrypt key:key iv:iv];

}

- (NSData *)YYY_AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv{

    char keyPtr[kCCKeySizeAES128 + 1];

    memset(keyPtr, 0, sizeof(keyPtr));

    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];



    char ivPtr[kCCBlockSizeAES128 + 1];

    memset(ivPtr, 0, sizeof(ivPtr));

    [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];



    NSUInteger dataLength = [self length];

    size_t bufferSize = dataLength + kCCBlockSizeAES128;

    void *buffer = malloc(bufferSize);



    size_t numBytesCrypted = 0;

    CCCryptorStatus cryptStatus = CCCrypt(operation,

                                          kCCAlgorithmAES128,

                                          kCCOptionPKCS7Padding | kCCOptionECBMode ,

                                          keyPtr,

                                          kCCBlockSizeAES128,

                                          ivPtr,

                                          [self bytes],

                                          dataLength,

                                          buffer,

                                          bufferSize,

                                          &numBytesCrypted);

    if (cryptStatus == kCCSuccess) {

        return [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];

    }

    free(buffer);

    return nil;

}
@end

hopper之后

void * -[NSData YYY_AES128EncryptWithKey:iv:](void * self, void * _cmd, void * arg2, void * arg3) {
    var_-24 = 0x0;
    objc_storeStrong(&var_-24, arg2);
    var_-32 = 0x0;
    objc_storeStrong(&var_-32, arg3);
    var_-80 = [[self YYY_AES128Operation:0x0 key:var_-24 iv:var_-32] retain];
    objc_storeStrong(&var_-32, 0x0);
    objc_storeStrong(&var_-24, 0x0);
    rax = [var_-80 autorelease];
    return rax;
}
void * -[NSData YYY_AES128Operation:key:iv:](void * self, void * _cmd, unsigned int arg2, void * arg3, void * arg4) {
    var_-104 = 0x0;
    objc_storeStrong(&var_-104, arg3);
    var_-112 = 0x0;
    objc_storeStrong(&var_-112, arg4);
    memset(&var_-32, 0x0, 0x11);
    [var_-104 getCString:&var_-32 maxLength:0x11 encoding:0x4];
    memset(&var_-64, 0x0, 0x11);
    [var_-112 getCString:&var_-64 maxLength:0x11 encoding:0x4];
    var_-120 = [self length];
    var_-136 = malloc(var_-120 + 0x10);
    var_-144 = 0x0;
    stack[2048] = [objc_retainAutorelease(self) bytes];
    if (CCCrypt(arg2, 0x0, 0x3, &var_-32, 0x10, &var_-64, stack[2048], var_-120, var_-136, var_-120 + 0x10, &var_-144) == 0x0) {
            var_-72 = [[NSData dataWithBytesNoCopy:var_-136 length:var_-144] retain];
    }
    else {
            free(var_-136);
            var_-72 = 0x0;
    }
    objc_storeStrong(&var_-112, 0x0);
    objc_storeStrong(&var_-104, 0x0);
    var_-256 = [var_-72 autorelease];
    if (*___stack_chk_guard == *___stack_chk_guard) {
            rax = var_-256;
    }
    else {
            rax = __stack_chk_fail();
    }
    return rax;
}

别人的

void * -[NSData AES128EncryptWithKey:iv:](void * self, void * _cmd, void * arg2, void * arg3) {
    rbx = [arg2 retain];
    r14 = [[self AES128operation:0x0 key:rbx iv:arg3] retain];
    [rbx release];
    rax = [r14 autorelease];
    return rax;
}
void * -[NSData AES128operation:key:iv:](void * self, void * _cmd, unsigned int arg2, void * arg3, void * arg4) {
    r12 = [arg3 retain];
    *(int8_t *)(&var_-80 + 0x10) = 0x0;
    var_-80 = intrinsic_movaps(var_-80, 0x0);
    r15 = [arg4 retain];
    [arg3 getCString:&var_-80 maxLength:0x11 encoding:0x4];
    [r12 release];
    *(int8_t *)(&var_-112 + 0x10) = 0x0;
    var_-112 = intrinsic_movaps(var_-112, 0x0);
    [arg4 getCString:&var_-112 maxLength:0x11 encoding:0x4];
    [r15 release];
    r15 = malloc([self length] + 0x10);
    var_-128 = 0x0;
    rbx = objc_retainAutorelease(self);
    [rbx bytes];
    [rbx length];
    rsp = (rsp - 0x30) + 0x30;
    if (CCCrypt(arg2, 0x0, 0x1, &var_-80, 0x10, &var_-112, stack[2048], stack[2049], stack[2050], stack[2051], stack[2052]) != 0x0) {
            free(r15);
            rdi = 0x0;
    }
    else {
            rdi = [[NSData dataWithBytesNoCopy:r15 length:var_-128] retain];
    }
    if (*___stack_chk_guard == *___stack_chk_guard) {
            rax = [rdi autorelease];
    }
    else {
            rax = __stack_chk_fail();
    }
    return rax;
}

区别在哪

kCCEncrypt = 0, 第一个参数arg2,传入没问题。

看cccrypt的第三个参数 

看到第三个参数不一样

enum {

    /* options for block ciphers */

    kCCOptionPKCS7Padding   = 0x0001,

    kCCOptionECBMode        = 0x0002

    /* stream ciphers currently have no options */

};

验证一下填充算法不同的加密结果

+(void)load{
    
    NSData *oData = [@"123467890" dataUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"%@",oData);
    
    NSLog(@"%@",[oData YYY_AES128EncryptWithKey:@"20003333" iv:@"AES"]);
    NSLog(@"%@",[oData YYY_AES128EncryptWithKey:@"20003333" iv:@"AES"]);
    
    NSData *myData = [oData YYY_AES128EncryptWithKey:@"20003333" iv:@"AES"];
    
    NSLog(@"%@",[oData AES128EncryptWithKey:@"20003333" iv:@"AES"]);
    NSLog(@"%@",[oData AES128EncryptWithKey:@"20003333" iv:@"AES"]);
    
    NSData *otherData = [oData AES128EncryptWithKey:@"20003333" iv:@"AES"];
    
    NSLog(@"%@",[myData YYY_AES128DecryptWithKey:@"20003333" iv:@"AES"]);
    NSLog(@"%@",[otherData AES128DecryptWithKey:@"20003333" iv:@"AES"]);
    
    NSLog(@"%@",[otherData YYY_AES128DecryptWithKey:@"20003333" iv:@"AES"]);
    NSLog(@"%@",[myData AES128DecryptWithKey:@"20003333" iv:@"AES"]);
    

}
<2020-03-19 05:30:37 +0000NSData+YYYYY.m:(20)>-+[NSData(YYYYY) load]-{length = 9, bytes = 0x313233343637383930}-

<2020-03-19 05:30:39 +0000NSData+YYYYY.m:(22)>-+[NSData(YYYYY) load]-{length = 16, bytes = 0x728adf7a267ddc6916e76f0342fd8e68}-

<2020-03-19 05:30:41 +0000NSData+YYYYY.m:(23)>-+[NSData(YYYYY) load]-{length = 16, bytes = 0x728adf7a267ddc6916e76f0342fd8e68}-

<2020-03-19 05:30:46 +0000NSData+YYYYY.m:(27)>-+[NSData(YYYYY) load]-{length = 16, bytes = 0x13f6bc9b49a4cc3022165ef5dee60f79}-

<2020-03-19 05:30:47 +0000NSData+YYYYY.m:(28)>-+[NSData(YYYYY) load]-{length = 16, bytes = 0x13f6bc9b49a4cc3022165ef5dee60f79}-

<2020-03-19 05:30:53 +0000NSData+YYYYY.m:(32)>-+[NSData(YYYYY) load]-{length = 9, bytes = 0x313233343637383930}-

<2020-03-19 05:30:57 +0000NSData+YYYYY.m:(33)>-+[NSData(YYYYY) load]-{length = 9, bytes = 0x313233343637383930}-

<2020-03-19 05:30:59 +0000NSData+YYYYY.m:(35)>-+[NSData(YYYYY) load]-{length = 9, bytes = 0x707760343637383930}-

<2020-03-19 05:31:02 +0000NSData+YYYYY.m:(36)>-+[NSData(YYYYY) load]-{length = 9, bytes = 0x707760343637383930}-

可以看到原始明文是0x313233343637383930。

使用kCCOptionPKCS7Padding | kCCOptionECBMode(简称03)加密后是0x728adf7a267ddc6916e76f0342fd8e68。

使用kCCOptionPKCS7Padding(简称01)加密后是0x13f6bc9b49a4cc3022165ef5dee60f79。

对03的密文使用03解密0x313233343637383930,

对01的密文使用01解密0x313233343637383930,

对01的密文使用03解密0x707760343637383930。

对03的密文使用01解密0x707760343637383930。

会导致前面几位不同。

这么简单的问题,去年的我竟然找不到解决办法。

总结:这是由相同的加密算法但使用了不同的填充算法引发的血案。

发布了130 篇原创文章 · 获赞 15 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/qq_15509071/article/details/104964824