Iphone - How to encrypt NSData with public key and decrypt with private key?

26,389

Solution 1

I have tried RSA Encryption and Decryption for NSString and you may well modify it and make it work for NSData

Add Security.Framework to your project bundle.

ViewController.h code is as follows:

#import <UIKit/UIKit.h>
#import <Security/Security.h>

@interface ViewController : UIViewController
{
SecKeyRef publicKey;
SecKeyRef privateKey;
    NSData *publicTag;
    NSData *privateTag;
}
- (void)encryptWithPublicKey:(uint8_t *)plainBuffer cipherBuffer:(uint8_t *)cipherBuffer;
- (void)decryptWithPrivateKey:(uint8_t *)cipherBuffer plainBuffer:(uint8_t *)plainBuffer;
- (SecKeyRef)getPublicKeyRef;
- (SecKeyRef)getPrivateKeyRef;
- (void)testAsymmetricEncryptionAndDecryption;
- (void)generateKeyPair:(NSUInteger)keySize;
@end

ViewController.m file code is as follows:

#import "ViewController.h"

const size_t BUFFER_SIZE = 64;
const size_t CIPHER_BUFFER_SIZE = 1024;
const uint32_t PADDING = kSecPaddingNone;
static const UInt8 publicKeyIdentifier[] = "com.apple.sample.publickey";
static const UInt8 privateKeyIdentifier[] = "com.apple.sample.privatekey";

@implementation ViewController

-(SecKeyRef)getPublicKeyRef { 

    OSStatus sanityCheck = noErr; 
    SecKeyRef publicKeyReference = NULL;

    if (publicKeyReference == NULL) { 
        [self generateKeyPair:512];
                NSMutableDictionary *queryPublicKey = [[NSMutableDictionary alloc] init];

        // Set the public key query dictionary.
        [queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
        [queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
        [queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
        [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];


        // Get the key.
        sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyReference);


        if (sanityCheck != noErr)
        {
            publicKeyReference = NULL;
        }


//        [queryPublicKey release];

    } else { publicKeyReference = publicKey; }

    return publicKeyReference; }

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}




- (void)testAsymmetricEncryptionAndDecryption {

    uint8_t *plainBuffer;
    uint8_t *cipherBuffer;
    uint8_t *decryptedBuffer;



    const char inputString[] = "How to Encrypt data with public key and Decrypt data with private key";
    int len = strlen(inputString);
    // TODO: this is a hack since i know inputString length will be less than BUFFER_SIZE
    if (len > BUFFER_SIZE) len = BUFFER_SIZE-1;

    plainBuffer = (uint8_t *)calloc(BUFFER_SIZE, sizeof(uint8_t));
    cipherBuffer = (uint8_t *)calloc(CIPHER_BUFFER_SIZE, sizeof(uint8_t));
    decryptedBuffer = (uint8_t *)calloc(BUFFER_SIZE, sizeof(uint8_t));

    strncpy( (char *)plainBuffer, inputString, len);

    NSLog(@"init() plainBuffer: %s", plainBuffer);
    //NSLog(@"init(): sizeof(plainBuffer): %d", sizeof(plainBuffer));
    [self encryptWithPublicKey:(UInt8 *)plainBuffer cipherBuffer:cipherBuffer];
    NSLog(@"encrypted data: %s", cipherBuffer);
    //NSLog(@"init(): sizeof(cipherBuffer): %d", sizeof(cipherBuffer));
    [self decryptWithPrivateKey:cipherBuffer plainBuffer:decryptedBuffer];
    NSLog(@"decrypted data: %s", decryptedBuffer);
    //NSLog(@"init(): sizeof(decryptedBuffer): %d", sizeof(decryptedBuffer));
    NSLog(@"====== /second test =======================================");

    free(plainBuffer);
    free(cipherBuffer);
    free(decryptedBuffer);
}

/* Borrowed from:
 * https://developer.apple.com/library/mac/#documentation/security/conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html
 */
- (void)encryptWithPublicKey:(uint8_t *)plainBuffer cipherBuffer:(uint8_t *)cipherBuffer
{

    NSLog(@"== encryptWithPublicKey()");

    OSStatus status = noErr;

    NSLog(@"** original plain text 0: %s", plainBuffer);

    size_t plainBufferSize = strlen((char *)plainBuffer);
    size_t cipherBufferSize = CIPHER_BUFFER_SIZE;

    NSLog(@"SecKeyGetBlockSize() public = %lu", SecKeyGetBlockSize([self getPublicKeyRef]));
    //  Error handling
    // Encrypt using the public.
    status = SecKeyEncrypt([self getPublicKeyRef],
                           PADDING,
                           plainBuffer,
                           plainBufferSize,
                           &cipherBuffer[0],
                           &cipherBufferSize
                           );
    NSLog(@"encryption result code: %ld (size: %lu)", status, cipherBufferSize);
    NSLog(@"encrypted text: %s", cipherBuffer);
}

- (void)decryptWithPrivateKey:(uint8_t *)cipherBuffer plainBuffer:(uint8_t *)plainBuffer
{
    OSStatus status = noErr;

    size_t cipherBufferSize = strlen((char *)cipherBuffer);

    NSLog(@"decryptWithPrivateKey: length of buffer: %lu", BUFFER_SIZE);
    NSLog(@"decryptWithPrivateKey: length of input: %lu", cipherBufferSize);

    // DECRYPTION
    size_t plainBufferSize = BUFFER_SIZE;

    //  Error handling
    status = SecKeyDecrypt([self getPrivateKeyRef],
                           PADDING,
                           &cipherBuffer[0],
                           cipherBufferSize,
                           &plainBuffer[0],
                           &plainBufferSize
                           );
    NSLog(@"decryption result code: %ld (size: %lu)", status, plainBufferSize);
    NSLog(@"FINAL decrypted text: %s", plainBuffer);

}



- (SecKeyRef)getPrivateKeyRef {
    OSStatus resultCode = noErr;
    SecKeyRef privateKeyReference = NULL;
//    NSData *privateTag = [NSData dataWithBytes:@"ABCD" length:strlen((const char *)@"ABCD")];
//    if(privateKey == NULL) {
        [self generateKeyPair:512];
        NSMutableDictionary * queryPrivateKey = [[NSMutableDictionary alloc] init];

        // Set the private key query dictionary.
        [queryPrivateKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
        [queryPrivateKey setObject:privateTag forKey:(__bridge id)kSecAttrApplicationTag];
        [queryPrivateKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
        [queryPrivateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];

        // Get the key.
        resultCode = SecItemCopyMatching((__bridge CFDictionaryRef)queryPrivateKey, (CFTypeRef *)&privateKeyReference);
        NSLog(@"getPrivateKey: result code: %ld", resultCode);

        if(resultCode != noErr)
        {
            privateKeyReference = NULL;
        }

//        [queryPrivateKey release];
//    } else {
//        privateKeyReference = privateKey;
//    }

    return privateKeyReference;
}


#pragma mark - View lifecycle



- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    privateTag = [[NSData alloc] initWithBytes:privateKeyIdentifier length:sizeof(privateKeyIdentifier)];
    publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];
    [self testAsymmetricEncryptionAndDecryption];

}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {
        return YES;
    }
}

- (void)generateKeyPair:(NSUInteger)keySize {
    OSStatus sanityCheck = noErr;
    publicKey = NULL;
    privateKey = NULL;

//  LOGGING_FACILITY1( keySize == 512 || keySize == 1024 || keySize == 2048, @"%d is an invalid and unsupported key size.", keySize );

    // First delete current keys.
//  [self deleteAsymmetricKeys];

    // Container dictionaries.
    NSMutableDictionary * privateKeyAttr = [[NSMutableDictionary alloc] init];
    NSMutableDictionary * publicKeyAttr = [[NSMutableDictionary alloc] init];
    NSMutableDictionary * keyPairAttr = [[NSMutableDictionary alloc] init];

    // Set top level dictionary for the keypair.
    [keyPairAttr setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
    [keyPairAttr setObject:[NSNumber numberWithUnsignedInteger:keySize] forKey:(__bridge id)kSecAttrKeySizeInBits];

    // Set the private key dictionary.
    [privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecAttrIsPermanent];
    [privateKeyAttr setObject:privateTag forKey:(__bridge id)kSecAttrApplicationTag];
    // See SecKey.h to set other flag values.

    // Set the public key dictionary.
    [publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecAttrIsPermanent];
    [publicKeyAttr setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
    // See SecKey.h to set other flag values.

    // Set attributes to top level dictionary.
    [keyPairAttr setObject:privateKeyAttr forKey:(__bridge id)kSecPrivateKeyAttrs];
    [keyPairAttr setObject:publicKeyAttr forKey:(__bridge id)kSecPublicKeyAttrs];

    // SecKeyGeneratePair returns the SecKeyRefs just for educational purposes.
    sanityCheck = SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttr, &publicKey, &privateKey);
//  LOGGING_FACILITY( sanityCheck == noErr && publicKey != NULL && privateKey != NULL, @"Something really bad went wrong with generating the key pair." );
    if(sanityCheck == noErr  && publicKey != NULL && privateKey != NULL)
    {
        NSLog(@"Successful");
    }
//  [privateKeyAttr release];
//  [publicKeyAttr release];
//  [keyPairAttr release];
}


@end

Let me know if you need more help.

Hope this helps.

Solution 2

NSData+AESCrypt.h

#import <Foundation/Foundation.h>

@interface NSData (AESCrypt)

- (NSData *)AES256EncryptWithKey:(NSString *)key;
- (NSData *)AES256DecryptWithKey:(NSString *)key;

+ (NSData *)dataWithBase64EncodedString:(NSString *)string;
- (id)initWithBase64EncodedString:(NSString *)string;

- (NSString *)base64Encoding;
- (NSString *)base64EncodingWithLineLength:(NSUInteger)lineLength;

- (BOOL)hasPrefixBytes:(const void *)prefix length:(NSUInteger)length;
- (BOOL)hasSuffixBytes:(const void *)suffix length:(NSUInteger)length;

NSData+AESCrypt.m

#import "NSData+AESCrypt.h"
#import <CommonCrypto/CommonCryptor.h>

static char encodingTable[64] = 
{
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
    'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
    'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
};

@implementation NSData (AESCrypt)

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

#pragma mark -

+ (NSData *)dataWithBase64EncodedString:(NSString *)string
{
   return [[[NSData allocWithZone:nil] initWithBase64EncodedString:string] autorelease];
}

- (id)initWithBase64EncodedString:(NSString *)string
{
   NSMutableData *mutableData = nil;

   if( string )
   {
      unsigned long ixtext = 0;
      unsigned long lentext = 0;
      unsigned char ch = 0;
      unsigned char inbuf[4], outbuf[3];
      short i = 0, ixinbuf = 0;
      BOOL flignore = NO;
      BOOL flendtext = NO;
      NSData *base64Data = nil;
      const unsigned char *base64Bytes = nil;

      // Convert the string to ASCII data.
      base64Data = [string dataUsingEncoding:NSASCIIStringEncoding];
      base64Bytes = [base64Data bytes];
      mutableData = [NSMutableData dataWithCapacity:base64Data.length];
      lentext = base64Data.length;

      while( YES )
     {
         if( ixtext >= lentext ) break;
         ch = base64Bytes[ixtext++];
         flignore = NO;

         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 = YES;
         else if( ch == '/' ) ch = 63;
         else flignore = YES;

         if( ! flignore )
         {
           short ctcharsinbuf = 3;
           BOOL flbreak = NO;

           if( flendtext ) 
           {
              if( ! ixinbuf ) break;
              if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
              else ctcharsinbuf = 2;
              ixinbuf = 3;
              flbreak = YES;
           }

            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++ )
                 [mutableData appendBytes:&outbuf[i] length:1];
           }

           if( flbreak )  break;
        }
     }
 }

  self = [self initWithData:mutableData];
  return self;
}

#pragma mark -

   - (NSString *)base64Encoding
   {
       return [self base64EncodingWithLineLength:0];
   }

   - (NSString *)base64EncodingWithLineLength:(NSUInteger)lineLength
   {
       const unsigned char   *bytes = [self bytes];
       NSMutableString *result = [NSMutableString stringWithCapacity:self.length];
       unsigned long ixtext = 0;
       unsigned long lentext = self.length;
       long ctremaining = 0;
       unsigned char inbuf[3], outbuf[4];
       unsigned short i = 0;
       unsigned short charsonline = 0, ctcopy = 0;
       unsigned long ix = 0;

       while( YES )
       {
           ctremaining = lentext - ixtext;
           if( ctremaining <= 0 ) break;

           for( i = 0; i < 3; i++ )
           {
               ix = ixtext + i;
               if( ix < lentext ) inbuf[i] = bytes[ix];
               else inbuf [i] = 0;
           }

           outbuf [0] = (inbuf [0] & 0xFC) >> 2;
           outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
           outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
           outbuf [3] = inbuf [2] & 0x3F;
           ctcopy = 4;

           switch( ctremaining )
           {
              case 1:
                 ctcopy = 2;
                 break;
              case 2:
                 ctcopy = 3;
                 break;
           }

          for( i = 0; i < ctcopy; i++ )
              [result appendFormat:@"%c", encodingTable[outbuf[i]]];

          for( i = ctcopy; i < 4; i++ )
              [result appendString:@"="];

          ixtext += 3;
          charsonline += 4;

          if( lineLength > 0 )
          {
             if( charsonline >= lineLength )
             {
                 charsonline = 0;
                 [result appendString:@"\n"];
             }
          }
     }

     return [NSString stringWithString:result];
  }
#pragma mark -
 - (BOOL)hasPrefixBytes:(const void *)prefix length:(NSUInteger)length
 {
     if( ! prefix || ! length || self.length < length ) return NO;
      return ( memcmp( [self bytes], prefix, length ) == 0 );
  }

  - (BOOL)hasSuffixBytes:(const void *)suffix length:(NSUInteger)length
  {
      if( ! suffix || ! length || self.length < length ) return NO;
       return ( memcmp( ((const char *)[self bytes] + (self.length - length)), suffix, length ) == 0  );
  }

You can use the following code:

NSData *encryptedData = [UIImagePNGRepresentation(/*your image*/) AES256EncryptWithKey:/*your enc key*/];

NSData *plainData = [encryptedData AES256DecryptWithKey:/*your enc key*/];

UIImage *img =[UIImage imageWithData:plainData];  
Share:
26,389

Related videos on Youtube

sachi
Author by

sachi

Updated on May 31, 2020

Comments

  • sachi
    sachi almost 4 years

    I am converting a UIImage to NSData. Now I need to encrypt that NSData using a public key and I need to decrypt using a private key. Please provide a step by step procedure. Which algorithm do I need to use? Is there any good library for encryption and decryption? Also provide some code snippet for encryption and decryption.

    • ott--
      ott-- about 12 years
      Once you give away your public key, you have no control over it anymore. Everyone can pass it to anyone else, that means encrypting data with your private key is a waste of time.
    • sachi
      sachi about 12 years
      @ParthBhatt really i am stuck. can u send the code sample to my personal mail id
    • Parth Bhatt
      Parth Bhatt about 12 years
      @sachi: Yes sure, but will it be fine if I can send it to you in the evening? Please provide your email Id.
    • sachi
      sachi about 12 years
      @ParthBhatt ok. [email protected]. Please help me. i am using xcode Version 3.2.6
  • Parth Bhatt
    Parth Bhatt about 12 years
    @sachi: Did this answer help you?
  • Sameera Chathuranga
    Sameera Chathuranga over 11 years
    i am getting this text as encrypted text - 4ÑÂÊá;è»–vJNàØmY—ú:º‰aé-™¬›qS•¿]~ΣOÍ™vIá%sjÂ…◊5¬s'6ÒW .. but i need base64 text. Do u have any solution for that? .. thanks
  • Nitesh Meshram
    Nitesh Meshram almost 11 years
    @ParthBhatt - how to get this -> static const UInt8 publicKeyIdentifier[] = "com.apple.sample.publickey"; static const UInt8 privateKeyIdentifier[] = "com.apple.sample.privatekey"; , I am having all the keys in file .der & .pem.
  • Devarshi
    Devarshi about 10 years
    Anyidea on how to encrypt it using private key and decrypt it using public key, basically I want to encrypt AES key as well as a string.
  • pregmatch
    pregmatch almost 10 years
    @Parth Bhatt can you explain your code little bit more. I want be able to encrypt 20kb of text. What is buffer_size and CIPHER_BUFFER_SIZE? also what does it mean "512" in generateKeyPair:512? can yo uhelp me with that?
  • pregmatch
    pregmatch almost 10 years
    @Parth Bhatt I want to be able to encrypt this for example: "{'message': 'All testimonials','response': [{'name': 'Ellie the Dog','photo': 'upload/people/TestimonialPhoto-Ellie1.jpg','text': 'Please take me on a walk.'},],'status': 1}"
  • Admin
    Admin over 9 years
    @pregmatch did you got it?
  • Satyam Raikar
    Satyam Raikar almost 9 years
    /*your enc Key*/ can be retrieved using reverse engineering the app if stored in app directly as string.
  • Lee Probert
    Lee Probert over 7 years
    Not using two keys either
  • HannahCarney
    HannahCarney about 6 years
    All those NSLogs are very dangerous as you can read the easily by plugging in a device to the console. Also can read in device logs.
  • Parth Bhatt
    Parth Bhatt about 6 years
    @HannahLouisaCarney NSLogs are added just for understanding about how it works . Best practice to follow is to remove all NSLog before going live. Thats an industry standard as far as security is considered.
  • vky
    vky over 5 years
    @Parth Bhatt dear hope fully your were good & fine. As per your answer,i tried your code,but could not understand some points could you please elaborate me.? First thing is.. static const UInt8 publicKeyIdentifier[] = "com.apple.sample.publickey"; what does you mean about that "com.apple.sample.publickey";...?? static const UInt8 privateKeyIdentifier[] = "com.apple.sample.privatekey"; And second one is ... what does you mean about const char inputString[] = "How to Encrypt data with public key and Decrypt data with private key"; I am waiting,respond as soon as possible Thanks