#import "ViewController.h"
#import <CommonCrypto/CommonCryptor.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *key = @"2A8B7BF7-9BC8-4991-8A84-DBA96F10EED2";
NSString *secret1 = @"1122334455";
NSString *secret = @"Xf0iDyPDDWBR5wnpT9keoA==";
NSData * encrypted = [[secret1 dataUsingEncoding:NSUTF8StringEncoding] dataEncryptedUsingAlgorithm:kCCAlgorithmAES128 key:[NSData dataWithBytes:[[key dataUsingEncoding:NSUTF8StringEncoding] bytes] length:16] initializationVector:[NSData dataWithBytes:[[key dataUsingEncoding:NSUTF8StringEncoding] bytes] length:16] options:kCCOptionPKCS7Padding error:nil];
NSLog(@"encrypted %@",encrypted);
NSString *str = [self base64forData:encrypted];
NSLog (@"String is %@",str);
// NSData *data1 = [self base64DataFromString:secret];
NSData *data = [encrypted decryptedDataUsingAlgorithm:kCCAlgorithmAES128 key:[NSData dataWithBytes:[[key dataUsingEncoding:NSUTF8StringEncoding] bytes] length:16] initializationVector:[[key dataUsingEncoding:NSUTF8StringEncoding] bytes] length:16] options:kCCOptionPKCS7Padding error:nil];
NSLog(@"data1 %@ %@",data,[secret1 dataUsingEncoding:NSUTF8StringEncoding]);
// NSLog(@"data1 %@", [NSString stringWithUTF8String:[data bytes]]);
}
- (NSString*)base64forData:(NSData*)theData
{
const uint8_t* input = (const uint8_t*)[theData bytes];
NSInteger length = [theData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger theIndex = (i / 3) * 4;
output[theIndex + 0] = table[(value >> 18) & 0x3F];
output[theIndex + 1] = table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] ;
}
- (NSData *)base64DataFromString: (NSString *)string
{
unsigned long ixtext, lentext;
unsigned char ch, inbuf[4], outbuf[3];
short i, ixinbuf;
Boolean flignore, flendtext = false;
const unsigned char *tempcstring;
NSMutableData *theData;
if (string == nil)
{
return [NSData data];
}
ixtext = 0;
tempcstring = (const unsigned char *)[string UTF8String];
lentext = [string length];
theData = [NSMutableData dataWithCapacity: lentext];
ixinbuf = 0;
while (true)
{
if (ixtext >= lentext)
{
break;
}
ch = tempcstring [ixtext++];
flignore = false;
if ((ch >= 'A') && (ch <= 'Z'))
{
ch = ch - 'A';
}
else if ((ch >= 'a') && (ch <= 'z'))
{
ch = ch - 'a' + 26;
}
else if ((ch >= '0') && (ch <= '9'))
{
ch = ch - '0' + 52;
}
else if (ch == '+')
{
ch = 62;
}
else if (ch == '=')
{
flendtext = true;
}
else if (ch == '/')
{
ch = 63;
}
else
{
flignore = true;
}
if (!flignore)
{
short ctcharsinbuf = 3;
Boolean flbreak = false;
if (flendtext)
{
if (ixinbuf == 0)
{
break;
}
if ((ixinbuf == 1) || (ixinbuf == 2))
{
ctcharsinbuf = 1;
}
else
{
ctcharsinbuf = 2;
}
ixinbuf = 3;
flbreak = true;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4)
{
ixinbuf = 0;
outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);
for (i = 0; i < ctcharsinbuf; i++)
{
[theData appendBytes: &outbuf[i] length: 1];
}
}
if (flbreak)
{
break;
}
}
}
return theData;
}
@end
And category for encryption
#import <Foundation/NSData.h>
#import <Foundation/NSError.h>
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonHMAC.h>
extern NSString * const kCommonCryptoErrorDomain;
@interface NSError (CommonCryptoErrorDomain)
+ (NSError *) errorWithCCCryptorStatus: (CCCryptorStatus) status;
@end
@interface NSData (CommonDigest)
- (NSData *) MD2Sum;
- (NSData *) MD4Sum;
- (NSData *) MD5Sum;
- (NSData *) SHA1Hash;
- (NSData *) SHA224Hash;
- (NSData *) SHA256Hash;
- (NSData *) SHA384Hash;
- (NSData *) SHA512Hash;
@end
@interface NSData (CommonCryptor)
- (NSData *) AES256EncryptedDataUsingKey: (id) key error: (NSError **) error;
- (NSData *) decryptedAES256DataUsingKey: (id) key error: (NSError **) error;
- (NSData *) DESEncryptedDataUsingKey: (id) key error: (NSError **) error;
- (NSData *) decryptedDESDataUsingKey: (id) key error: (NSError **) error;
- (NSData *) CASTEncryptedDataUsingKey: (id) key error: (NSError **) error;
- (NSData *) decryptedCASTDataUsingKey: (id) key error: (NSError **) error;
@end
@interface NSData (LowLevelCommonCryptor)
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
error: (CCCryptorStatus *) error;
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error;
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
initializationVector: (id) iv // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error;
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
error: (CCCryptorStatus *) error;
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error;
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
initializationVector: (id) iv // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error;
@end
@interface NSData (CommonHMAC)
- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm;
- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm key: (id) key;
@end
.m File
#import <Foundation/Foundation.h>
#import "NSData+CommonCrypto.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonHMAC.h>
NSString * const kCommonCryptoErrorDomain = @"CommonCryptoErrorDomain";
@implementation NSError (CommonCryptoErrorDomain)
+ (NSError *) errorWithCCCryptorStatus: (CCCryptorStatus) status
{
NSString * description = nil, * reason = nil;
switch ( status )
{
case kCCSuccess:
description = NSLocalizedString(@"Success", @"Error description");
break;
case kCCParamError:
description = NSLocalizedString(@"Parameter Error", @"Error description");
reason = NSLocalizedString(@"Illegal parameter supplied to encryption/decryption algorithm", @"Error reason");
break;
case kCCBufferTooSmall:
description = NSLocalizedString(@"Buffer Too Small", @"Error description");
reason = NSLocalizedString(@"Insufficient buffer provided for specified operation", @"Error reason");
break;
case kCCMemoryFailure:
description = NSLocalizedString(@"Memory Failure", @"Error description");
reason = NSLocalizedString(@"Failed to allocate memory", @"Error reason");
break;
case kCCAlignmentError:
description = NSLocalizedString(@"Alignment Error", @"Error description");
reason = NSLocalizedString(@"Input size to encryption algorithm was not aligned correctly", @"Error reason");
break;
case kCCDecodeError:
description = NSLocalizedString(@"Decode Error", @"Error description");
reason = NSLocalizedString(@"Input data did not decode or decrypt correctly", @"Error reason");
break;
case kCCUnimplemented:
description = NSLocalizedString(@"Unimplemented Function", @"Error description");
reason = NSLocalizedString(@"Function not implemented for the current algorithm", @"Error reason");
break;
default:
description = NSLocalizedString(@"Unknown Error", @"Error description");
break;
}
NSMutableDictionary * userInfo = [[NSMutableDictionary alloc] init];
[userInfo setObject: description forKey: NSLocalizedDescriptionKey];
if ( reason != nil )
[userInfo setObject: reason forKey: NSLocalizedFailureReasonErrorKey];
NSError * result = [NSError errorWithDomain: kCommonCryptoErrorDomain code: status userInfo: userInfo];
#if !__has_feature(objc_arc)
[userInfo release];
#endif
return ( result );
}
@end
#pragma mark -
@implementation NSData (CommonDigest)
- (NSData *) MD2Sum
{
unsigned char hash[CC_MD2_DIGEST_LENGTH];
(void) CC_MD2( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_MD2_DIGEST_LENGTH] );
}
- (NSData *) MD4Sum
{
unsigned char hash[CC_MD4_DIGEST_LENGTH];
(void) CC_MD4( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_MD4_DIGEST_LENGTH] );
}
- (NSData *) MD5Sum
{
unsigned char hash[CC_MD5_DIGEST_LENGTH];
(void) CC_MD5( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_MD5_DIGEST_LENGTH] );
}
- (NSData *) SHA1Hash
{
unsigned char hash[CC_SHA1_DIGEST_LENGTH];
(void) CC_SHA1( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA1_DIGEST_LENGTH] );
}
- (NSData *) SHA224Hash
{
unsigned char hash[CC_SHA224_DIGEST_LENGTH];
(void) CC_SHA224( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA224_DIGEST_LENGTH] );
}
- (NSData *) SHA256Hash
{
unsigned char hash[CC_SHA256_DIGEST_LENGTH];
(void) CC_SHA256( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA256_DIGEST_LENGTH] );
}
- (NSData *) SHA384Hash
{
unsigned char hash[CC_SHA384_DIGEST_LENGTH];
(void) CC_SHA384( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA384_DIGEST_LENGTH] );
}
- (NSData *) SHA512Hash
{
unsigned char hash[CC_SHA512_DIGEST_LENGTH];
(void) CC_SHA512( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA512_DIGEST_LENGTH] );
}
@end
@implementation NSData (CommonCryptor)
- (NSData *) AES256EncryptedDataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmAES128
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
- (NSData *) decryptedAES256DataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmAES128
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
- (NSData *) DESEncryptedDataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmDES
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
- (NSData *) decryptedDESDataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmDES
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
- (NSData *) CASTEncryptedDataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmCAST
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
- (NSData *) decryptedCASTDataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmCAST
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
@end
static void FixKeyLengths( CCAlgorithm algorithm, NSMutableData * keyData, NSMutableData * ivData )
{
NSUInteger keyLength = [keyData length];
switch ( algorithm )
{
case kCCAlgorithmAES128:
{
if ( keyLength < 16 )
{
[keyData setLength: 16];
}
else if ( keyLength < 24 )
{
[keyData setLength: 24];
}
else
{
[keyData setLength: 32];
}
break;
}
case kCCAlgorithmDES:
{
[keyData setLength: 8];
break;
}
case kCCAlgorithm3DES:
{
[keyData setLength: 24];
break;
}
case kCCAlgorithmCAST:
{
if ( keyLength < 5 )
{
[keyData setLength: 5];
}
else if ( keyLength > 16 )
{
[keyData setLength: 16];
}
break;
}
case kCCAlgorithmRC4:
{
if ( keyLength > 512 )
[keyData setLength: 512];
break;
}
default:
break;
}
[ivData setLength: [keyData length]];
}
@implementation NSData (LowLevelCommonCryptor)
- (NSData *) _runCryptor: (CCCryptorRef) cryptor result: (CCCryptorStatus *) status
{
size_t bufsize = CCCryptorGetOutputLength( cryptor, (size_t)[self length], true );
void * buf = malloc( bufsize );
size_t bufused = 0;
size_t bytesTotal = 0;
*status = CCCryptorUpdate( cryptor, [self bytes], (size_t)[self length],
buf, bufsize, &bufused );
if ( *status != kCCSuccess )
{
free( buf );
return ( nil );
}
bytesTotal += bufused;
// From Brent Royal-Gordon (Twitter: architechies):
// Need to update buf ptr past used bytes when calling CCCryptorFinal()
*status = CCCryptorFinal( cryptor, buf + bufused, bufsize - bufused, &bufused );
if ( *status != kCCSuccess )
{
free( buf );
return ( nil );
}
bytesTotal += bufused;
return ( [NSData dataWithBytesNoCopy: buf length: bytesTotal] );
}
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key
error: (CCCryptorStatus *) error
{
return ( [self dataEncryptedUsingAlgorithm: algorithm
key: key
initializationVector: nil
options: 0
error: error] );
}
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key
options: (CCOptions) options
error: (CCCryptorStatus *) error
{
return ( [self dataEncryptedUsingAlgorithm: algorithm
key: key
initializationVector: nil
options: options
error: error] );
}
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key
initializationVector: (id) iv
options: (CCOptions) options
error: (CCCryptorStatus *) error
{
CCCryptorRef cryptor = NULL;
CCCryptorStatus status = kCCSuccess;
NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);
NSMutableData * keyData, * ivData;
if ( [key isKindOfClass: [NSData class]] )
keyData = (NSMutableData *) [key mutableCopy];
else
keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
if ( [iv isKindOfClass: [NSString class]] )
ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
else
ivData = (NSMutableData *) [iv mutableCopy]; // data or nil
#if !__has_feature(objc_arc)
[keyData autorelease];
[ivData autorelease];
#endif
// ensure correct lengths for key and iv data, based on algorithms
FixKeyLengths( algorithm, keyData, ivData );
status = CCCryptorCreate( kCCEncrypt, algorithm, options,
[keyData bytes], [key length], [keyData bytes],
&cryptor );
if ( status != kCCSuccess )
{
if ( error != NULL )
*error = status;
return ( nil );
}
NSData * result = [self _runCryptor: cryptor result: &status];
if ( (result == nil) && (error != NULL) )
*error = status;
CCCryptorRelease( cryptor );
return ( result );
}
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
error: (CCCryptorStatus *) error
{
return ( [self decryptedDataUsingAlgorithm: algorithm
key: key
initializationVector: nil
options: 0
error: error] );
}
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error
{
return ( [self decryptedDataUsingAlgorithm: algorithm
key: key
initializationVector: nil
options: options
error: error] );
}
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
initializationVector: (id) iv // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error
{
CCCryptorRef cryptor = NULL;
CCCryptorStatus status = kCCSuccess;
NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);
NSMutableData * keyData, * ivData;
if ( [key isKindOfClass: [NSData class]] )
keyData = (NSMutableData *) [key mutableCopy];
else
keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
if ( [iv isKindOfClass: [NSString class]] )
ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
else
ivData = (NSMutableData *) [iv mutableCopy]; // data or nil
#if !__has_feature(objc_arc)
[keyData autorelease];
[ivData autorelease];
#endif
// ensure correct lengths for key and iv data, based on algorithms
FixKeyLengths( algorithm, keyData, ivData );
status = CCCryptorCreate( kCCDecrypt, algorithm, options,
[keyData bytes], [keyData length], [ivData bytes],
&cryptor );
if ( status != kCCSuccess )
{
if ( error != NULL )
*error = status;
return ( nil );
}
NSData * result = [self _runCryptor: cryptor result: &status];
if ( (result == nil) && (error != NULL) )
*error = status;
CCCryptorRelease( cryptor );
return ( result );
}
@end
@implementation NSData (CommonHMAC)
- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm
{
return ( [self HMACWithAlgorithm: algorithm key: nil] );
}
- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm key: (id) key
{
NSParameterAssert(key == nil || [key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
NSData * keyData = nil;
if ( [key isKindOfClass: [NSString class]] )
keyData = [key dataUsingEncoding: NSUTF8StringEncoding];
else
keyData = (NSData *) key;
// this could be either CC_SHA1_DIGEST_LENGTH or CC_MD5_DIGEST_LENGTH. SHA1 is larger.
unsigned char buf[CC_SHA1_DIGEST_LENGTH];
CCHmac( algorithm, [keyData bytes], [keyData length], [self bytes], [self length], buf );
return ( [NSData dataWithBytes: buf length: (algorithm == kCCHmacAlgMD5 ? CC_MD5_DIGEST_LENGTH : CC_SHA1_DIGEST_LENGTH)] );
}
@end
Encryption is working fine but i am not able to decrypt it please suggest.
Aes 128 encryption uses the Initial vector value you can pass the value using SHA256