[MAC] - OpenSSL dependency removal and use Crypto APIS

Hello,

In my MAC application, need to overcome the dependency of Open ssl and use apple APIS to acheive the same.


I have a similar issue where I need to get away from OpenSSL in my app, as it is not encouraged by apple to use them. I do not want to statically link the openssl to my project. I want to achieve the same using crypto APIS. In one of the apple link, it says

OpenSSL

Although OpenSSL is commonly used in the open source community, OpenSSL does not provide a stable API from version to version. For this reason, although OS X provides OpenSSL libraries, the OpenSSL libraries in OS X are deprecated, and OpenSSL has never been provided as part of iOS. Use of the OS X OpenSSL libraries by apps is strongly discouraged.

If your app depends on OpenSSL, you should compile OpenSSL yourself and statically link a known version of OpenSSL into your app. This use of OpenSSL is possible on both OS X and iOS. However, unless you are trying to maintain source compatibility with an existing open source project, you should generally use a different API.

Common Crypto and Security Transforms are the recommended alternatives for general encryption. CFNetwork and Secure Transport are the recommended alternatives for secure communications.

======

But if we use the crypto APIs similar to how it works in IOS, the APIs are not generating the expected values. One of the stack overflow discussion link says that the frameworks of IOS and MAC are similar, but not identical

https:/

Can you please guide us on what needs to be used achieve the operations of open SSL through apple APIs in MAC ?

======

I have tried using SecKeyGeneratePair to generate the public private key pair. The API is giving just the instance with no values in it.

{

NSString *strTag = nil;

NSString *privateTagString = nil;

NSString *publicTagString = nil;


if( privateTag == nil && publicTag == nil && symmetricTag == nil )

{

strTag = [[HelpMethods UUIDString] lowercaseString]; // This generated a random UUID to have it as a private and a public reference

privateTagString = [NSString stringWithFormat:@"%@.private",strTag];

publicTagString = [NSString stringWithFormat:@"%@.public",strTag];

privateTag = [[NSData alloc] initWithData:[privateTagString dataUsingEncoding:NSUTF16StringEncoding]];

publicTag = [[NSData alloc] initWithData:[publicTagString dataUsingEncoding:NSUTF16StringEncoding]] ;

symmetricTag = [[NSData alloc] initWithBytes:symmetricKeyIdentifier length:sizeof(symmetricKeyIdentifier)];

}

NSMutableDictionary * privateKeyAttr = nil;

NSMutableDictionary * publicKeyAttr = nil;

NSMutableDictionary * keyPairAttr = nil;

OSStatus sanityCheck = noErr;

privateKeyAttr = [[NSMutableDictionary alloc] init];

publicKeyAttr = [[NSMutableDictionary alloc] init];

keyPairAttr = [[NSMutableDictionary alloc] init];

/*************/

// Set the private key dictionary.

[privateKeyAttr setObject:[NSNumber numberWithBool:FALSE] forKey:(id)kSecAttrIsPermanent];

[privateKeyAttr setObject:privateTag forKey:(id)kSecAttrApplicationTag];


/*************/

// Set the public key dictionary.

[publicKeyAttr setObject:[NSNumber numberWithBool:FALSE] forKey:(id)kSecAttrIsPermanent];

[publicKeyAttr setObject:publicTag forKey:(id)kSecAttrApplicationTag];

/************/

[keyPairAttr setObject:( id )kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];

[keyPairAttr setObject:[NSString stringWithFormat:@"%lu", (unsigned long)nKeySize] forKey:( id )kSecAttrKeySizeInBits];

[keyPairAttr setObject:privateKeyAttr forKey:(id)kSecPrivateKeyAttrs];

[keyPairAttr setObject:publicKeyAttr forKey:(id)kSecPublicKeyAttrs];

/*************/

// Generate he key pair

sanityCheck = SecKeyGeneratePair( (CFDictionaryRef)keyPairAttr, &publicKeyRef, &privateKeyRef);


privateKeyAttr = nil;

publicKeyAttr = nil;

keyPairAttr = nil;

}

nKeySize used here is 2048


After this, I tried get the mod data of the public key, which is giving me 0 bytes.

======

Also SecKeyGeneratePair documentation says

  • In macOS, add the key-value pairs to the parameters dictionary directly. The specified attributes are applied to both the public and private keys.
  • In iOS, add dictionaries for the keys and to the parameters dictionary, and provide the attributes in those dictionaries. The attributes specified in these dictionaries are added to either the public or private key, respectively, allowing you to apply separate attributes to each key.

Can you please explain on this or point to some sample where understanding gets better ?


Please guide us in what needs to used to overcome the dependency of Openssl. What other ways to convert Open ssl to apple APIs ?


Thanks,

Champa

Replies

Can you please guide us on what needs to be used achieve the operations of open SSL through apple APIs in MAC ?

It’s hard to answer this in the general case because OpenSSL has a huge API surface. However, the CryptoCompatibility sample code shows how to do a lot of common operations (encryption, both symmetric and asymmetric, cryptographic hash, HMAC, and so on) in a way that’s compatible with OpenSSL. You should start there and then post back if you hit specific snags.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hello,


Thank you so much for the quick reply.


Yes shall go through the link provided above and get back.


To be more specific, In general, does same crypto code expected to work for both IOS and MAC applications.

Code written in the above mail works for IOS and not for MAC. So, are the frameworks not identical was my basic query. The code posted above gives a different output when run as IOS app and when run as MAC app. The API used above is SecKeyGeneratePair.

My basic intention is to generate the private publick RSA key programmatically and use that accordingly for signing a particular data.

Hope I am more clear now.


Thanks,

Champa

Hello,


I did go through the CryptoCompatibility pointed by you but this did not help me in generating the public/private RSA key combination.


I am looking out for the APIs as in given below link for OSX application, because this link is working for and IOS application.

https://developer.apple.com/library/content/samplecode/CryptoExercise/Listings/Classes_SecKeyWrapper_m.html


If we try the same IOS example on OSX, SecKeyGeneratePair API does not fail but not able to export the valid keys from it.


Can you please guide through.


Thanks,

Champa

In general, does same crypto code expected to work for both IOS and MAC applications.

Yes. The one caveat here is asymmetric encryption where you have to write macOS- and iOS-specific code if you want to deploy to systems earlier than macOS 10.12 or iOS 10.

If we try the same IOS example on OSX, SecKeyGeneratePair API does not fail but not able to export the valid keys from it.

Right. This is an example of what I discussed above. There are three ways to export a public key:

  • On modern systems you can use

    SecKeyCopyExternalRepresentation
  • On older versions of macOS you can use the various APIs in

    <Security/SecImportExport.h>
  • On older versions of iOS you have to use the barely supported technique shown by CryptoExercise

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you.


I just tried for 10.12 with the above mentioned steps and looks ok. Shall try the other set of APIs ( <Security/SecImportExport.h> ) for OS versions less than 10.12 and then get back if There are questions from my end.


Thanks again,

Champa