1

I am using the following in perl to encrypt the body of a http:// response.

use Crypt::CBC;
my $cipher = Crypt::CBC->new(
                            -key    => 'testpasswordof32Charlength',
                            -cipher => "Crypt::OpenSSL::AES"
                            );


print $cipher->encrypt($data);

and in iOS, using the following to unencrypt:

- (NSData *)AES256DecryptWithKey:(NSString *)key {
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

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

    NSUInteger dataLength = [self length];

    //See the doc: For block ciphers, the output size will always be less than or
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

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

    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }

    free(buffer); //free the buffer;
    return nil;
}

I then do the following to call the perl routine on the server

NSData *receivedData = [NSURLConnection
                                sendSynchronousRequest:theRequest
                                returningResponse:&theResponse
                                error:&theError];

[receivedData AES256DecryptWithKey:@"testpasswordof32Charlength"];

I get garbage in the receivedData NSData ... any idea why? I am probably missing something plain and (non-simple in decryption)... I ensured that I was using CBC on iOS by using kCCOptionPKCS7Padding. Any ideas?

Pulling (what little is left of my) hair out!

jww
  • 97,681
  • 90
  • 411
  • 885
Jann
  • 2,214
  • 3
  • 28
  • 45
  • See http://stackoverflow.com/questions/12231033/openssl-equivalent-for-aes256encryptwithkey-method/12240694#12240694 – Rob Napier Sep 18 '12 at 21:06
  • Will try RNCrypter, but are you saying this: `NSData *decryptedData = [RNDecryptor decryptData: receivedData withPassword:@"testpasswordof32Charlength" error:&error];` would act as a drop-in-replacement? *without* changing the perl side? Or was I doing something wrong in perl? – Jann Sep 18 '12 at 21:13
  • If you use the OpenSSL subclass for RNCryptor, then it is compatible with openssl. I assume that the perl is also compatible with openssl. As noted, openssl uses a non-standard and problematic format. It's not going to be supported by anything that doesn't say specifically "supports openssl." – Rob Napier Sep 18 '12 at 21:21
  • You will need to check, however, what cipher is being used on both sides. I assume you're using AES-256, which RNCryptor uses, because of your "testpasswordof32Charlength" (just assuming, since "32 characters" in the password has nothing at all to do with the key size). – Rob Napier Sep 18 '12 at 21:23
  • Yes, I am using AES-256. Ok, well, "Unknown header" is what I got when trying to decrypt when using RNDecryptor. Off to try the openssl subclass :( – Jann Sep 18 '12 at 21:27
  • 1
    Okay, how about this: Anyone have ANY perl code to generate encrypted data that iOS can decode? – Jann Sep 18 '12 at 22:10

0 Answers0