Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 479 Vote(s) - 3.39 Average
  • 1
  • 2
  • 3
  • 4
  • 5
AES Encryption for an NSString on the iPhone

#1
Can anybody point me in the right direction to be able to encrypt a string, returning another string with the encrypted data? (I've been trying with AES256 encryption.) I want to write a method which takes two NSString instances, one being the message to encrypt and the other being a 'passcode' to encrypt it with - I suspect I'd have to generate the encryption key with the passcode, in a way that can be reversed if the passcode is supplied with the encrypted data. The method should then return an NSString created from the encrypted data.

I've tried the technique detailed in [the first comment on this post][1], but I've had no luck so far. Apple's [CryptoExercise][2] certainly has something, but I can't make sense of it... I've seen lots of references to [CCCrypt][3], but it's failed in every case I've used it.

I would also have to be able to decrypt an encrypted string, but I hope that's as simple as kCCEncrypt/kCCDecrypt.


[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

Reply

#2
Since you haven't posted any code, it's difficult to know exactly which problems you're encountering. However, the blog post you link to does seem to work pretty decently... aside from the extra comma in each call to `CCCrypt()` which caused compile errors.

A later comment on that post includes [this adapted code][1], which works for me, and seems a bit more straightforward. If you include their code for the NSData category, you can write something like this: (Note: The `printf()` calls are only for demonstrating the state of the data at various points — in a real application, it wouldn't make sense to print such values.)

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSString *key = @"my password";
NSString *secret = @"text to encrypt";

NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding];
NSData *cipher = [plain AES256EncryptWithKey:key];
printf("%s\n", [[cipher description] UTF8String]);

plain = [cipher AES256DecryptWithKey:key];
printf("%s\n", [[plain description] UTF8String]);
printf("%s\n", [[[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding] UTF8String]);

[pool drain];
return 0;
}

Given this code, and the fact that encrypted data will not always translate nicely into an NSString, it may be more convenient to write two methods that wrap the functionality you need, in forward and reverse...

- (NSData*) encryptString:(NSString*)plaintext withKey:(NSString*)key {
return [[plaintext dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptWithKey:key];
}

- (NSString*) decryptData:(NSData*)ciphertext withKey:(NSString*)key {
return [[[NSString alloc] initWithData:[ciphertext AES256DecryptWithKey:key]
encoding:NSUTF8StringEncoding] autorelease];
}

This definitely works on Snow Leopard, and **@Boz** reports that CommonCrypto is part of the Core OS on the iPhone. Both 10.4 and 10.5 have `/usr/include/CommonCrypto`, although 10.5 has a man page for `CCCryptor.3cc` and 10.4 doesn't, so YMMV.

---

**EDIT:** See [this follow-up question][2] on using Base64 encoding for representing encrypted data bytes as a string (if desired) using safe, lossless conversions.


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#3
I have put together a collection of categories for NSData and NSString which uses solutions found on [Jeff LaMarche's blog][1] and [some hints][2] by Quinn Taylor here on Stack Overflow.

It uses categories to extend NSData to provide AES256 encryption and also offers an extension of NSString to BASE64-encode encrypted data safely to strings.

Here's an example to show the usage for encrypting strings:

NSString *plainString = @"This string will be encrypted";
NSString *key = @"YourEncryptionKey"; // should be provided by a user

NSLog( @"Original String: %@", plainString );

NSString *encryptedString = [plainString AES256EncryptWithKey:key];
NSLog( @"Encrypted String: %@", encryptedString );

NSLog( @"Decrypted String: %@", [encryptedString AES256DecryptWithKey:key] );

Get the full source code here:

>

[To see links please register here]


Thanks for all the helpful hints!

-- Michael


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#4
@owlstead, regarding your request for "a cryptographically secure variant of one of the given answers," please see [RNCryptor][1]. It was designed to do exactly what you're requesting (and was built in response to the problems with the code listed here).

RNCryptor uses PBKDF2 with salt, provides a random IV, and attaches HMAC (also generated from PBKDF2 with its own salt. It support synchronous and asynchronous operation.


[1]:

[To see links please register here]

Reply

#5
I waited a bit on @QuinnTaylor to update his answer, but since he didn't, here's the answer a bit more clearly and in a way that it will load on XCode7 (and perhaps greater). I used this in a Cocoa application, but it likely will work okay with an iOS application as well. Has no ARC errors.

**Paste before any @implementation section in your AppDelegate.m or AppDelegate.mm file.**

#import <CommonCrypto/CommonCryptor.h>

@implementation NSData (AES256)

- (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

**Paste these two functions in the @implementation class you desire. In my case, I chose @implementation AppDelegate in my AppDelegate.mm or AppDelegate.m file.**

- (NSString *) encryptString:(NSString*)plaintext withKey:(NSString*)key {
NSData *data = [[plaintext dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptWithKey:key];
return [data base64EncodedStringWithOptions:kNilOptions];
}

- (NSString *) decryptString:(NSString *)ciphertext withKey:(NSString*)key {
NSData *data = [[NSData alloc] initWithBase64EncodedString:ciphertext options:kNilOptions];
return [[NSString alloc] initWithData:[data AES256DecryptWithKey:key] encoding:NSUTF8StringEncoding];
}

Reply

#6
Please use the below mentioned URL to encrypt string using AES excryption with
key and IV values.

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through