Question

I have an iOS mobile app that encrypts data and stores it in files in the app sandbox. Files are encrypted using CCCrypt() as follows:

    CCCryptorStatus aCryptStatus = CCCrypt(kCCEncrypt, 
                                       kCCAlgorithmAES128, 
                                       kCCOptionPKCS7Padding,
                                       aKeyPtr, 
                                       kCCKeySizeAES256,
                                       aIVPtr,
                                       [self bytes], 
                                       aDataLength, 
                                       aBuffer, 
                                       aBufferSize, 
                                       &aNumBytesEncrypted);

The key is 256 bits long, the IV is 128 bits long. I'm a not an expert with encryption, but this should be using CBC mode (default for CCCrypt()) and it is my understanding that the PKCS#7 padding option specified here is equivalent to openssl's PKCS#5 padding.

The data is written to a file as follows:

     NSData* aSerializedData = [[self serialize]  dataUsingEncoding:NSUTF8StringEncoding];
     NSData* aEncryptedData = [aSerializedData AES256EncryptWithKey:ENCKey 
                                               InitializationVector:ENCIv]; 
     NSFileManager* aFileManager = [[NSFileManager alloc] init];
     BOOL aFileWritten = [aFileManager createFileAtPath:aFilePath 
                                               contents:aEncryptedData 
                                             attributes:nil];

I have attempted to decrypt the file using openssl as follows (key and iv replaced with 0's):

$ openssl enc -aes-128-cbc -d -K 00000000000000000000000000000000 -iv 0000000000000000 -in encrypted.dat -out decrypted.txt 

and

$ openssl enc -aes-256-cbc -d -K 00000000000000000000000000000000 -iv 0000000000000000 -in encrypted.dat -out decrypted.txt 

Both return the same error:

bad decrypt 28969:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:/SourceCache/OpenSSL098/OpenSSL098-50/src/crypto/evp/evp_enc.c:330:

I've also tried other modes and other options such as -nosalt and -a. None have returned the cleartext.

I've spent hours trying to find an example of how to do this anywhere online, but nothing that has helped me resolve the problem. Help would be appreciated.

==========

Answer: The key in CCCrypt is a 32 char string that gets converted to 256 bits. The key expected by openssl is the 64 hex digits from the binary representation of that string. Similarly, the iv in CCCrypt is a 16 char string that gets converted into 128 bits. The iv expected by openssl is the hex representation of that string. Once I used the hex representations of those two, it decrypted easily.

Was it helpful?

Solution

The openssl key and iv as specified with -K and -iv are specified as a hex representation of the binary data.
From the openssl docs:

the actual key to use: this must be represented as a string comprised only of hex digits.

Both of the openssl keys in the example are 128 bits, for AES 256 they need to be 256 bits. The iv must be block size, 128 bits but in the above example the iv is only 64 bits.

I tested and this works:

uint8_t *zeros     = calloc(1, 256);
NSData  *keyData   = [NSData dataWithBytes:zeros length:16];
NSData  *ivData    = [NSData dataWithBytes:zeros length:16];
NSData  *clearData = [@"0123456789abcdef" dataUsingEncoding:NSUTF8StringEncoding];

NSData *encryptedData = [AESTest doCipher:clearData iv:ivData key:keyData context:kCCEncrypt error:&error];
[encryptedData writeToFile:@"/Users/dan/Desktop/encrypted.dat" atomically:YES];

openssl enc -aes-128-cbc -d -K 00000000000000000000000000000000 -iv 00000000000000000000000000000000 -in /Users/dan/Desktop/encrypted.dat -out /Users/dan/Desktop/decrypted.txt

cat /Users/dan/Desktop/decrypted.txt
0123456789abcdef

For the method doCipher see this SO answer

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top