sopor
sopor

Reputation: 46

Encrypt string with AES in Python and IOS

I am trying to encrypt a string with AES in both IOS with CCCrypt and in Python with Crypto. However I seem to get different results. Anyone has any ideas why?

I am trying to use 256 bit AES with null IV and CBC.

Python code:

key = 'verysecretkey1111111111111111111'

IV = 16 * '\x00'    
mode = AES.MODE_CBC
cipher = AES.new(key, AES.MODE_CBC, IV)

y='aaaabbbbccccdddd'
length = 16 - (len(y) % 16)
y += chr(length)*length

encoded = cipher.encrypt(y)
print base64.b64encode(encoded)

The result is gyL9jv7bTgLz8xZQx/GLYNVnVrrwo6pLsc5Ew4Vl8Uk=

Objective C code

char keyPtr[kCCKeySizeAES256 ];
bzero( keyPtr, sizeof( keyPtr ) );

// fetch key data
[key getCString:keyPtr maxLength:sizeof( keyPtr  encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [self length];


size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );

size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128,   kCCOptionPKCS7Padding,
                                      keyPtr, kCCKeySizeAES256,
                                      NULL /* initialization vector (optional) */,
                                      [self bytes], dataLength, /* input */
                                      buffer, bufferSize, /* output */
                                      &numBytesEncrypted );

The result is DskVKDMGxFWLGSYszL/mEersVv9zq9PK9bPIV5UgLbs=

Upvotes: 0

Views: 1090

Answers (1)

zaph
zaph

Reputation: 112875

There is a problem with calling the Objective-C method and given incomplete code understanding that error is difficult.

This statement in the Question is definitely incorrect:

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

There are two problems:
1. A missing closing parenthesis to sizeof.
2. Space must be reserved for the trailing null a "C" string requires:

char keyPtr[kCCKeySizeAES256+1];  
bzero( keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSASCIIStringEncoding];

Note that the method getCString: returns status but is not checked, if it has been there error would have been apparent. Error status is a developer's best friend.

But as seen in the code below there is a simpler way to handle the key.

Here a an example with a result matching the Python code"

NSString *key  = @"verysecretkey1111111111111111111";
NSString *data = @"aaaabbbbccccdddd";

NSData *dataIn  = [data dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [key  dataUsingEncoding:NSUTF8StringEncoding];

CCCryptorStatus ccStatus   = kCCSuccess;
size_t          cryptBytes = 0;
NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];

ccStatus = CCCrypt( kCCEncrypt,
                   kCCAlgorithmAES128,
                   kCCOptionPKCS7Padding,
                   keyData.bytes, kCCKeySizeAES256,
                   NULL,
                   dataIn.bytes, dataIn.length,
                   dataOut.mutableBytes, dataOut.length,
                   &cryptBytes);

if (ccStatus != kCCSuccess) {
    NSLog(@"CCCrypt status: %d", ccStatus);
}
dataOut.length = cryptBytes;

NSString *objcEncrypted = [dataOut base64EncodedStringWithOptions:0];
NSLog(@"objcEncrypted: %@", objcEncrypted);

Output:

objcEncrypted: gyL9jv7bTgLz8xZQx/GLYNVnVrrwo6pLsc5Ew4Vl8Uk=

Upvotes: 1

Related Questions