-1

I am trying to encrypt a string with 'AES-128 CBC with IV'. Here is the input parameter and expected output:

Key: 000102030405060708090A0B0C0D0E0F

IV: 00102030405060708090A0B0C0D0E0F0

Input data: EA010B23CDA9B16F0001020304050607

Output: B773C36749E87D3F8FED98FE52026A15

I have verified the output on this web site: http://extranet.cryptomathic.com/aescalc/index?key=000102030405060708090A0B0C0D0E0F&iv=00102030405060708090A0B0C0D0E0F0&input=EA010B23CDA9B16F0001020304050607&mode=cbc&action=Encrypt&output=B773C36749E87D3F8FED98FE52026A15

How to encrypt a string with AES-128 CBC with IV in objective C? (With same result as http://extranet.cryptomathic.com/aescalc) I am trying to get the encrypted string - B773C36749E87D3F8FED98FE52026A15 , but no luck.



I have tried to use this library for the encryption: https://github.com/Pakhee/Cross-platform-AES-encryption/tree/master/iOS

Here is my objective c code:

NSString* data = @"EA010B23CDA9B16F0001020304050607";
NSString* key = @"000102030405060708090A0B0C0D0E0F";
NSString* iv = @"00102030405060708090A0B0C0D0E0F0";


NSData *encryptedData = [[StringEncryption alloc] encrypt:[@"EA010B23CDA9B16F0001020304050607" dataUsingEncoding:NSUTF8StringEncoding] key:key iv:iv];
NSLog(@"encryptedData %@", encryptedData);

The output of encryptedData is: <68f8ed75 e79f2ba2 c80e67a2 f0c84b7a c4b07fd1 59e937e5 14644cba c0ddb60c 40502375 7798e7a1 58bd05a5 b3d9e7bd>



I expect the value of *encryptedData should be <42373733 43333637 34394538 37443346 38464544 39384645 35323032 36413135>, which is hex of B773C36749E87D3F8FED98FE52026A15

I have tried another library - https://github.com/dev5tec/FBEncryptor

NSData* _data = [data dataUsingEncoding:NSUTF8StringEncoding];
NSData* _key = [key dataUsingEncoding:NSUTF8StringEncoding];
NSData* _iv = [iv dataUsingEncoding:NSUTF8StringEncoding];


NSData *encryptedData2 = [FBEncryptorAES encryptData:_data key:_key iv:_iv];
NSLog(@"encryptedData2 = %@", encryptedData2);

Output is <2beea977 aef69eb1 ed9f6dd0 7bf5f1ce d1e5df46 2cbf8465 773f122d 03267abb 2e113d9b 07189268 4fd6babe 7b1c0056>

It seems that I am using wrong library or I have wrong input to the encryption function. Any recommendation of AES library for objective c?

mobile app Beginner
  • 1,651
  • 3
  • 26
  • 40
  • 1
    You mean that: http://stackoverflow.com/questions/7520615/how-to-convert-an-nsdata-into-an-nsstring-hex-string ? – Larme Jul 31 '16 at 18:50
  • Thanks Larme, I have tried the example of converting NSData to NSString. But it returns monster character like >èaµ[ü#Õ-­ÅÄ ,o©vÖ®·¬Î/® ÊFØ qÈ5Ëlg~ . I am not sure my problem is NSData conversion or I use the library in a wrong way – mobile app Beginner Aug 01 '16 at 13:31
  • What did you do exactly to get that? Did you tried that: `NSUInteger capacity = encryptedData.length * 2; NSMutableString *sbuf = [NSMutableString stringWithCapacity:capacity]; const unsigned char *buf = encryptedData.bytes; NSInteger i; for (i=0; i< encryptedData.length; ++i) {[sbuf appendFormat:@"%02X", (NSUInteger)buf[i]];} NSString *encryptedString = [sbuf copy]`? – Larme Aug 01 '16 at 13:38
  • Sorry for the wrong information, I get 3EE861B55BFC23D50E2DADC5C40D032C6FA976D601AEB7ACCE2F8B86AE801020CA46D81E1E162071C835CB6C677E8283 (It is the output of my encryptedData variable without space, < and >) after the using the suggested algorithm. But that is not my expected output. Therefore I tried to use another algorithm to convert the hexstring to string with the algorithm suggest - http://stackoverflow.com/questions/6421282/how-to-convert-hex-to-nsstring-in-objective-c – mobile app Beginner Aug 01 '16 at 14:34
  • So your issue wasn't totally about `encryptedString`, but more importantly about `encryptedData` which was wrong? – Larme Aug 01 '16 at 15:57
  • Thanks Larme, I figured out that the problem is not related to NSData conversion. It seems that it is problem of using AES encryption library. I edited the question. – mobile app Beginner Aug 01 '16 at 17:07
  • The problem is about NSData conversion conversion from hexadecimal to data. If you are still interested I this I can provide sample code with Common Crypto that provide the same results as Cryptomathic. FBEncryptor also uses Common Crypto and accepts Base64 input. – zaph Aug 02 '16 at 02:15
  • Thanks zaph, do you mean I created NSData input from hexadecimal in a wrong way? and do I need to convert my input to Base64 first when I use FBEncryptor? – mobile app Beginner Aug 02 '16 at 03:33

1 Answers1

2

Common Crypto is the correct thing to use for encryption for iOS and OSX. The issue it to provide the correct input.

The input key, iv and data appear to be in hexadecimal. Cryptomathic expects it inputs to be in hexadecimal and it's output is in hexadecimal so it works correctly.

But the ObjC code uses:

NSString* data = @"EA010B23CDA9B16F0001020304050607";
NSData* _data = [data dataUsingEncoding:NSUTF8StringEncoding];

which uses the hexadecimal as a character string.
Instead use a hex to data conversion such as @Larme linked to, see the first comment.

From the sizes of the input and output it appears you are using PKCS#7 padding which adds a full block of padding if the input is an exact multiple of the block size, Cryptomathic does not add PKCS#7 padding.

Update

@interface Crypt : NSObject
+ (NSData *)aes128Data:(NSData *)dataIn;
+ (NSData *)dataFromHexString:(NSString *)hexString;
@end

@implementation Crypt

+ (NSData *)aes128Data:(NSData *)dataIn
             operation:(CCOperation)operation  // kCC Encrypt, Decrypt
                   key:(NSData *)key
               options:(CCOptions)options      // kCCOption PKCS7Padding, ECBMode,
                    iv:(NSData *)iv
                 error:(NSError **)error
{
    CCCryptorStatus ccStatus   = kCCSuccess;
    size_t          cryptBytes = 0;
    NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];

    ccStatus = CCCrypt( operation,
                       kCCAlgorithmAES,
                       options,
                       key.bytes, key.length,
                       iv.bytes,
                       dataIn.bytes, dataIn.length,
                       dataOut.mutableBytes, dataOut.length,
                       &cryptBytes);

    if (ccStatus == kCCSuccess) {
        dataOut.length = cryptBytes;
    }
    else {
        if (error) {
            *error = [NSError errorWithDomain:@"kEncryptionError"
                                         code:ccStatus
                                     userInfo:nil];
        }
        dataOut = nil;
    }

    return dataOut;
}

+ (NSData *)dataFromHexString:(NSString *)hexString {
    char buf[3];
    buf[2] = '\0';
    unsigned char *bytes = malloc([hexString length]/2);
    unsigned char *bp = bytes;
    for (CFIndex i = 0; i < [hexString length]; i += 2) {
        buf[0] = [hexString characterAtIndex:i];
        buf[1] = [hexString characterAtIndex:i+1];
        char *b2 = NULL;
        *bp++ = strtol(buf, &b2, 16);
    }

    return [NSData dataWithBytesNoCopy:bytes length:[hexString length]/2 freeWhenDone:YES];
}

@end

NSString *dataHexString = @"EA010B23CDA9B16F0001020304050607";
NSString *keyHexString = @"000102030405060708090A0B0C0D0E0F";
NSString *ivHexString = @"00102030405060708090A0B0C0D0E0F0";

NSLog(@"dataHexString: %@", dataHexString);
NSLog(@"keyHexString:  %@", keyHexString);
NSLog(@"ivHexString:   %@", ivHexString);

NSData *data = [Crypt dataFromHexString:dataHexString];
NSData *key  = [Crypt dataFromHexString:keyHexString];
NSData *iv   = [Crypt dataFromHexString:ivHexString];

NSLog(@"data: %@", data);
NSLog(@"key:  %@", key);
NSLog(@"iv:   %@", iv);

NSError *error;
NSData *encryptedData = [Crypt
                         aes128Data:data
                         operation:kCCEncrypt
                         key:key
                         options:0
                         iv:iv
                         error:&error];

NSLog(@"encryptedData %@", encryptedData);

Output:

dataHexString: EA010B23CDA9B16F0001020304050607
keyHexString:  000102030405060708090A0B0C0D0E0F
ivHexString:   00102030405060708090A0B0C0D0E0F0

data: <ea010b23 cda9b16f 00010203 04050607>
key:  <00010203 04050607 08090a0b 0c0d0e0f>
iv:   <00102030 40506070 8090a0b0 c0d0e0f0>

encryptedData: <b773c367 49e87d3f 8fed98fe 52026a15>

Note encryptedData matches the Cryptomathic result.

zaph
  • 111,848
  • 21
  • 189
  • 228
  • Thanks zaph, it seems that this link - http://stackoverflow.com/questions/7520615/how-to-convert-an-nsdata-into-an-nsstring-hex-string is about converting NSData into NSSting. But for my case, I need to convert NSString (hexadecimal) to NSData. Is there any library can do the conversion? – mobile app Beginner Aug 02 '16 at 03:53
  • I tried to convert the NSString to NSData like this - http://stackoverflow.com/questions/2338975/convert-hex-data-string-to-nsdata-in-objective-c-cocoa . But is still cannot get the correct encryption result. – mobile app Beginner Aug 02 '16 at 03:57
  • Apple has not provided such a library for some reason only Apple knows. See my update code for such a method. – zaph Aug 04 '16 at 14:10