Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AES Encryption CryptLib in iOS 13 not working

My application uses AES 256 encryption to encrypt a string. The same code that was used before is generating a different result. This problem started when iOS 13 was released. And it happens only to applications that are shipped to the store or built with Xcode 11.

Here is the code used for the encryption:


- (NSData *)encrypt:(NSData *)plainText key:(NSString *)key  iv:(NSString *)iv {  
    char keyPointer[kCCKeySizeAES256+2],// room for terminator (unused) ref: https://devforums.apple.com/message/876053#876053  
    ivPointer[kCCBlockSizeAES128+2];  
    BOOL patchNeeded;  
    bzero(keyPointer, sizeof(keyPointer)); // fill with zeroes for padding  

    patchNeeded= ([key length] > kCCKeySizeAES256+1);  
    if(patchNeeded)  
    {  
        NSLog(@"Key length is longer %lu", (unsigned long)[[self md5:key] length]);  
        key = [key substringToIndex:kCCKeySizeAES256]; // Ensure that the key isn't longer than what's needed (kCCKeySizeAES256)  
    }  

    //NSLog(@"md5 :%@", key);  
    [key getCString:keyPointer maxLength:sizeof(keyPointer) encoding:NSUTF8StringEncoding];  
    [iv getCString:ivPointer maxLength:sizeof(ivPointer) encoding:NSUTF8StringEncoding];  

    if (patchNeeded) {  
        keyPointer[0] = '\0';  // Previous iOS version than iOS7 set the first char to '\0' if the key was longer than kCCKeySizeAES256  
    }  

    NSUInteger dataLength = [plainText length];  

    //see https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/CCryptorCreateFromData.3cc.html  
    // For block ciphers, the output size will always be less than or equal to the input size plus the size of one block.  
    size_t buffSize = dataLength + kCCBlockSizeAES128;  
    void *buff = malloc(buffSize);  

    size_t numBytesEncrypted = 0;  
    //refer to http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-36064/CommonCrypto/CommonCryptor.h  
    //for details on this function  
    //Stateless, one-shot encrypt or decrypt operation.  
    CCCryptorStatus status = CCCrypt(kCCEncrypt, /* kCCEncrypt, etc. */  
                                     kCCAlgorithmAES128, /* kCCAlgorithmAES128, etc. */  
                                     kCCOptionPKCS7Padding, /* kCCOptionPKCS7Padding, etc. */  
                                     keyPointer, kCCKeySizeAES256, /* key and its length */  
                                     ivPointer, /* initialization vector - use random IV everytime */  
                                     [plainText bytes], [plainText length], /* input  */  
                                     buff, buffSize,/* data RETURNED here */  
                                     &numBytesEncrypted);  
    if (status == kCCSuccess) {  
        return [NSData dataWithBytesNoCopy:buff length:numBytesEncrypted];  
    }  

    free(buff);  
    return nil;  
}  


- (NSString *) encryptPlainTextWith:(NSString *)plainText key:(NSString *)key iv:(NSString *)iv {  
    return [[[[CryptLib alloc] init] encrypt:[plainText dataUsingEncoding:NSUTF8StringEncoding] key:[[CryptLib alloc] sha256:key length:32] iv:iv] base64EncodedStringWithOptions:0];  
} 
/** 

* This function computes the SHA256 hash of input string 
* @param key input text whose SHA256 hash has to be computed 
* @param length length of the text to be returned 
* @return returns SHA256 hash of input text 
*/  
- (NSString*) sha256:(NSString *)key length:(NSInteger) length{  
    const char *s=[key cStringUsingEncoding:NSASCIIStringEncoding];  
    NSData *keyData=[NSData dataWithBytes:s length:strlen(s)];  

    uint8_t digest[CC_SHA256_DIGEST_LENGTH]={0};  
    CC_SHA256(keyData.bytes, (CC_LONG)keyData.length, digest);  
    NSData *out=[NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];  
    NSString *hash=[out description];  
    hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];  
    hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];  
    hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];  

    if(length > [hash length])  
    {  
        return  hash;  
    }  
    else  
    {  
        return [hash substringToIndex:length];  
    }  
}

##

I would like to know if something in the code path has changed in the way it works. The method called to do the encryptions is "encryptPlainTextWith". Thanks in advance.

like image 864
Abdul Nasir B A Avatar asked Sep 25 '19 12:09

Abdul Nasir B A


People also ask

How do I enable AES 256 encryption?

Navigate to Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption. Double-click the “Choose drive encryption method and cipher strength” setting. Select Enabled, click the drop-down box, and select AES 256-bit. Click OK to save your change.

Can AES work in CBC mode?

The Cipher Block Chaining (CBC) mode is a typical block cipher mode of operation using block cipher algorithm. In this version, we provide Data Encryption Standard (DES) and Advanced Encryption Standard (AES) processing ability, the cipherkey length for DES should be 64 bits, and 128/192/256 bits for AES.


1 Answers

Inside:

- (NSString*) sha256:(NSString *)key length:(NSInteger) length

I replaced

NSString *hash=[out description];

To

NSString *hash=[out debugDescription];

And everything got back to normal. Cheers Happy coding.

Alternative Solution as per @Rob Napier

create separate function for converting NSData to Hex

#pragma mark - String Conversion
-(NSString*)hex:(NSData*)data{
     NSMutableData *result = [NSMutableData dataWithLength:2*data.length];
     unsigned const char* src = data.bytes;
     unsigned char* dst = result.mutableBytes;
     unsigned char t0, t1;

     for (int i = 0; i < data.length; i ++ ) {
          t0 = src[i] >> 4;
          t1 = src[i] & 0x0F;

          dst[i*2] = 48 + t0 + (t0 / 10) * 39;
          dst[i*2+1] = 48 + t1 + (t1 / 10) * 39;
     }

     return [[NSString alloc] initWithData:result encoding:NSASCIIStringEncoding];
}

After that Inside:

- (NSString*) sha256:(NSString *)key length:(NSInteger) length

I replaced

NSString *hash=[out description];

To

NSString *hash = [self hex:out];
like image 64
Abdul Nasir B A Avatar answered Sep 27 '22 20:09

Abdul Nasir B A