39

I am working on a simple app in objective-C that uses RSA Algorithm. I want to use it on Server/Client Communications. I need help in RSA Algorithm Implementation in iOS/iPhone.

  • I have knowledge of encryption and decryption.
  • I want an opensource library or code to add into my project.
  • I have to go though CommonCryptor.h.
Amir iDev
  • 1,257
  • 2
  • 15
  • 29
  • possible duplicate of [Iphone - How to encrypt NSData with public key and decrypt with private key?](http://stackoverflow.com/questions/10072124/iphone-how-to-encrypt-nsdata-with-public-key-and-decrypt-with-private-key) – bobobobo Apr 17 '13 at 20:44

2 Answers2

28

I have tried RSA Encryption and Decryption for NSString. Here is the code:

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[] = "This is a test demo for RSA Implementation in Objective C";
    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

Here is where I originally posted my answer : Iphone - How to encrypt NSData with public key and decrypt with private key?

Let me know if you need more help.

Hope this helps.

Community
  • 1
  • 1
Parth Bhatt
  • 19,381
  • 28
  • 133
  • 216
  • Dear Parth Bhatt, I am thankful for you help but i didn't see the encrypted data to be dencrypted in text form. – Amir iDev Apr 19 '12 at 10:31
  • @AmirIphone: Ok fine. But can you please let me know as of what is output of: `NSLog(@"FINAL decrypted text: %s", plainBuffer);` and `NSLog(@"encrypted text: %s", cipherBuffer);` that you get? – Parth Bhatt Apr 19 '12 at 11:04
  • @AmirIphone: Can you please tell me what you get as the output to Logs?? – Parth Bhatt Apr 19 '12 at 13:09
  • Final Decrypted text: ÕçêÛÈ7◊ƒÛ¡⁄Í,—óŒw!c˘∫0^ Encrypted Text: ÊJÚO – Amir iDev Apr 19 '12 at 13:18
  • I think you are getting something wrong. As on my side I have pasted this code from the tutorial I have made and this works fine for me. Can you tell me what you are passing initially as `inputString`? – Parth Bhatt Apr 19 '12 at 13:20
  • I am passing same as you passed... const char inputString[] = "Mitul bhai and Parth and Devang and Gajendra are iPhone Dev"; – Amir iDev Apr 19 '12 at 14:05
  • @AmirIphone: OK this image is blocked by firewall at my work place so may be I will reach home and help you out with this in the evening. – Parth Bhatt Apr 20 '12 at 07:16
  • How can i send you image now :( because i have to complete a task about this. and do you have any idea about Chilkat IPhone Objective-C Libraries. SKYPE: AMIRAKRAM.NXB – Amir iDev Apr 20 '12 at 07:26
  • @ParthBhatt... I am waiting for Correction from your Side – Amir iDev Apr 23 '12 at 11:16
  • 1
    @ParthBhatt Did you find any method to export the private key? I am trying to encrypt text at iphone and decrypt at server side. But I couldn't manage to export modulus and exponent (or in any format) of private key. – Jan Jun 01 '12 at 09:07
  • @ParthBhatt nevermind I generated the key with openssl. Created DER certificate and Used that certificate to encrypt data and verify signature. – Jan Jun 04 '12 at 08:06
  • @Jan can you post that solution which you got using DER certificate. I am too stuck with RSA encryption in iOS and its not working. – Janak Nirmal Aug 09 '12 at 08:26
  • 1
    @ParthBhatt i m getting the same error like AmirIphone getting ... do u have any solution for that .. thanks - My Encrypted text is - 4ÑÂÊá;è»–vJNàØmY—ú:º‰aé-™¬›qS•¿]~ΣOÍ™vIá%sjÂ…◊5¬s'6ÒW like this .. but i need Base64 text – Sameera Chathuranga Dec 06 '12 at 09:39
  • @Parth Bhatt I have encrypted text and public key from server. I want to decrypt text, how to implement it with your code? Should I change 'com.apple.sample.publickey' with public key that I get from server? – inot Dec 15 '12 at 20:26
  • @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 how this works with key files?? – Nitesh Meshram May 24 '13 at 02:49
  • 1
    How do I encrypt a String with more than 64 chars. I have a string of 800 characters. – NNikN Feb 18 '14 at 19:52
  • 1
    I have a public key (.pem) with password; how can it use it with the code above? – oOEric Aug 03 '15 at 06:16
  • @ParthBhatt Please add in Swift too. – Amir iDev Nov 05 '16 at 10:42
  • how will I get the generated public and private key values? – Ranu Dhurandhar Apr 17 '20 at 08:19
11

It's very cool! However i think it should not be a subclass of a UIViewController, but an NSObject, i changed and it works for me, here it is:

NOTE: ALL WORK IS THANKED TO @Parth Bath

RSAManager.h

@interface RSAManager : NSObject
{
   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

RSAManager.m

#import "RSAManager.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 RSAManager

- (id)init
{
   self = [super init];

   if(self) {

      privateTag = [[NSData alloc] initWithBytes:privateKeyIdentifier length:sizeof(privateKeyIdentifier)];
      publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];
      [self testAsymmetricEncryptionAndDecryption];
   }

   return self;
}

-(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)testAsymmetricEncryptionAndDecryption {

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



   const char inputString[] = "This is a test demo for RSA Implementation in Objective C";
   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;
}

- (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
Zoltan Varadi
  • 2,468
  • 2
  • 34
  • 51
  • 1
    I hope you can help me with this. What is BUFFER_SIZE? I need to be able to encrypt/decrypt 20-100KB of text. With you methods I get only first 64 characters encrypted/decrypted. Can you explain that little bit more or point me in right direction so I can read about it. – pregmatch May 21 '14 at 16:15
  • 2
    You typically encrypt the data with a symmetric algo like AES and a random key and then encrypt the AES key with RSA. – zaph Jun 18 '14 at 19:45
  • I'm getting a EXC_BAD_ACCESS at `encryptWithPublicKey:cipherBuffer:` in `NSLog(@"SecKeyGetBlockSize() public = %lu", SecKeyGetBlockSize([self getPublicKeyRef]));` because `getPublicKeyRef` returns nil – Nat Jul 14 '14 at 09:24
  • //getting this data I want the key in base64 encoded form – Ranu Dhurandhar Apr 18 '20 at 10:10