开发者

Any cocoa source code for AES encryption decryption?

I am searching for some cocoa code on AES encryption and I did some google search for it. I found this very useful link - http://iphonedevelopment.blogspot.com/2009/02/strong-encryption-for-cocoa-cocoa-touch.html. So I tried it but it did not work for me.

Can anyone suggest me s开发者_运维百科ome useful link or source code which can help me to implement it in my sample application.


I use a simple category on NSData that uses the built-in CommonCrypto framework to do AES 256-bit encryption. I use this on the Mac but it should work OK on iPhone too:

#import <CommonCrypto/CommonCryptor.h>
@implementation NSData (AESAdditions)
- (NSData*)AES256EncryptWithKey:(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 numBytesEncrypted    = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          NULL /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted);

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

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

- (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;
}
@end


AES128 encryption is available on the iPhone in the CommonCrypto framework. The relevant functions are in the CommonCryptor.h header.

You can create a cryptor like so:

// Assume key and keylength exist
CCCryptorRef cryptor;
if(kCCSuccess != CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES128, 0, key, keyLength, NULL, &cryptor))
  ; //handle error

// Repeatedly call CCCryptorUpdate to encrypt the data

CCCryptorRelease(cryptor);

It seems from the question and the link that you are looking for example implementations of AES. I would not recommend this- use Apple's implementation!

It looks like http://pastie.org/297563.txt might help you also, but I haven't tested it.


All examples I found didn't work for me, so I changed the solution above. This one works for me and uses the Google-Lib for Base64 stuff:

+ (NSData *)AES256DecryptWithKey:(NSString *)key data:(NSData*)data encryptOrDecrypt:(CCOperation)encryptOrDecrypt {

    // '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];

    if (encryptOrDecrypt == kCCDecrypt)
    {
        data = [GTMBase64 decodeData:data];
    }

        NSUInteger dataLength = [data 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(encryptOrDecrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCKeySizeAES256,
                                          NULL /* initialization vector (optional) */,
                                          [data bytes], dataLength, /* input */
                                          buffer,       bufferSize, /* output */
                                          &numBytesDecrypted);

    if (cryptStatus != kCCSuccess){ 
        NSLog(@"ERROR WITH FILE ENCRYPTION / DECRYPTION");
        return nil;
    }

    NSData *result;

    if (encryptOrDecrypt == kCCDecrypt)
    {
        result = [NSData dataWithBytes:(const void *)buffer length:(NSUInteger)numBytesDecrypted];
    }
    else
    {
        NSData *myData = [NSData dataWithBytes:(const void *)buffer length:(NSUInteger)numBytesDecrypted];
        result = [GTMBase64 encodeData:myData];
    }

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


thanks for the great category extension. One thing that I've discovered - when you use CCCrypt with an algorithm stronger then 64 bit, you need to be compliant to the BIS export regulations. See the iTunes Connect FAQ for more details. Even if you use Apple's inbuild crypto api you need to get approval from the BIS.

There was a discussion on sf about this topic before (in context of ssl usage):

Using SSL in an iPhone App - Export Compliance

Best Regards Chris

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜