Kind of a followup to my previous question to: How do I get the initialization vector (iv) from OpenSSL encrypted data
I'm using OpenSSL
command line utility to encrypt a string and then attempting to use <CommonCrypto/CommonCryptor.h>
to decrypt the string on an iPhone. Using Dropbox SDK, an xml file with encrypted strings is loaded onto the iPhone where my app attempts to parse and decrypt strings within this file.
Here's an example of the openssl command:
printf %s "Hello" | openssl enc -aes-128-cbc -K 00ff349830193845af43984758690213 -iv 0 -base64
The above base 64 string is placed in an XML file which is then parsed by the app.
I'm using Matt Gallagher's NSData addition to decode the base64 text. I'm assuming that's working correctly; I haven't really found a good way to test it. (Source: http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html).
Here's the method to decode the encrypted string.
The key is an NSString in this case equal to @"00ff349830193845af43984758690213"
.
+ (NSString *)string:(NSString *)encryptedString withAES128Key:(NSString *)key {
// decode base64, from Matt Gallagher's NSData category
NSData *b64DecodedData = [NSData dataFromBase64String:encryptedString];
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
// fyi, I plan to replace this later with a random iv
NSData *ivData = [@"00000000000000000000000000000000" dataUsingEncoding:NSUTF8StringEncoding];
// decrypt the string
NSData *decodedData = [self doCipher:b64DecodedData iv:ivData key:keyData context:kCCDecrypt];
NSString *unencryptedString = [[NSString alloc] initWithBytes:[decodedData bytes] length:[decodedData length] encoding:NSUTF8StringEncoding];
return [unencryptedString autorelease];
}
Here's the method that does the actual decrypting: (Credit for this method goes to a fellow stackoverflow user.)
+ (NSData *)doCipher:(NSData *)dataIn
iv:(NSData *)iv
key:(NSData *)symmetricKey
context:(CCOperation)encryptOrDecrypt
{
CCCryptorStatus ccStatus = kCCSuccess;
size_t cryptBytes = 0; // Number of bytes moved to buffer.
NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];
ccStatus = CCCrypt( encryptOrDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
[symmetricKey bytes],
kCCKeySizeAES128,
iv,
dataIn.bytes,
dataIn.length,
dataOut.mutableBytes,
dataOut.length,
&cryptBytes);
// error occurs here, error -4304 kCCDecodeError
if (ccStatus != kCCSuccess) {
// Handle error
NSLog(@"CCCrypt status: %d", ccStatus);
}
dataOut.length = cryptBytes;
return dataOut;
}
An error occurs, error code -4304
which is kCCDecodeError
because ccStatus
is not equal to kCCSuccess
.
I feel the key and iv are not being set as NSData objects correctly. OpenSSL requires the key and iv to be hex values, which I have done and careful to set them to exactly 128 bits. However, I think I'm missing something in converting those strings to NSData for the doCipher
method.
Any help is greatly appreciated! Been toying with this all day.