Integrating cryptography into a swift app

I am porting my Android app over to iOS and need to integrate encryption for communication with an existing server.

I need to be able to use AES-CBC and RSA-ECB.

My research has led me to the CommonCrypto library, but I have been stuck on this for days now, not finding how to integrate the library into my XCode project.

I am using XCode version 12.2 (not sure what version of swift comes with that though).

The methods I have tried to get CommonCrypto into the project are adding import CommonCrypto into the swift file, or adding #import <CommonCrypto/CommonCrypto.h> into the bridging header. Both of these makes XCode complain saying it cannot compile the Obective-C module.

In addition, I have not been able to find documentation explaining the correct way of using the library.

I need to :

  • Generate public and private keys for AES
  • Generate public and private keys for RSA
  • Encrypt and decrypt with AES-CBC with PKCS5 padding
  • Encrypt and decrypt with RSA-EBC with PKCS1 padding

Please note that I cannot change the encryption standards used.

Should I stick with CommonCrypto, go with OpenSSL, another fairly future proof solution ?

I would really appreciate help and guidance with this, please.

(Sorry, could not find any better tags)

Answered by DTS Engineer in 715432022

CommonCrypto is an Apple Open Source C library (no lib file ?) which requires an Objective-C wrapper, hence the CryptoCompatibility sample code.

You’re a bit off in the weeds here:

  • While Common Crypto is open source, the open source code shows a lot of stuff that’s not API. If you’re using Common Crypto in a product, stick with the APIs in your platform SDK.

  • The implementation of Common Crypto is within the System framework, aka libSystem. Xcode automatically links you to that.

  • It’s always been possible to call Common Crypto from Swift.

  • Historically it was tricky to use from Swift because there was no module map, and so the obvious thing, import CommonCrypto, didn’t work. We fixed that a while back. I don’t know if the fix is in Xcode 12, but it’s definitely in all versions of Xcode 13.

  • Having said that, it’s still not easy to use from Swift, because it requires a detailed understanding of how to use C APIs from Swift. Folks who have that experience can use Common Crypto from Swift just fine. If you don’t have that experience, it would be better to start by using it from Objective-C and then work out how to interact with that code from Swift.

  • I wrote CryptoCompatibility long before Swift was a thing, which is why it doesn’t have Swift support.

I already mix C++/Objective-C++ and have a bridging header

Cool. Then do this:

  1. Grab the operation from CryptoCompatibility that best matches your requirements and add its .h and .m files to your product.

  2. Include the .h file in your bridging header.

  3. Use that operation from your Swift code.

All the CryptoCompatibility operations work in terms of types that bridge reasonably well into Swift, like NSData bridging to Data. The same can’t be said for Common Crypto (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Please note that I cannot change the encryption standards used.

OK. That rules out the Apple CryptoKit, because it only supports modern cryptographic algorithms, and those algorithms are anything but that [1]. That means you have to use Common Crypto, for the symmetric key stuff, and SecKey, for the asymmetric key stuff.

It’s perfectly possible to use these APIs from Swift but it’s not a lot of fun. My advice is that you start with the CryptoCompatibility sample code, which implements all of these algorithms in Objective-C. Once you have that running, you can then decide whether it’s worth your time porting them to Swift.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Well, AES is OK, but it’s undermined by CBC and ECB.

Hi Quinn,

Thank you for your reply.

you can then decide whether it’s worth your time porting them to Swift.

There is really no decision to make, it would appear that I have to go with that - if I keep with CommonCrypto, unless there is a "better" option (???).

So, from what I see, CommonCrypto is an Apple Open Source C library (no lib file ?) which requires an Objective-C wrapper, hence the CryptoCompatibility sample code.

Can you confirm that I do not need to adjust the settings of the Swift app to do this (I already mix C++/Objective-C++ and have a bridging header ) ?

When I compare the include dir on the open source page - here - there are considerably more headers.

Within my XCode sdk installation I have :

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto ->
CommonCrypto.h
CommonCryptoError.h
CommonCryptor.h
CommonDigest.h
CommonHMAC.h
CommonKeyDerivation.h
CommonRandom.h
CommonSymmetricKeywrap.h
module.modulemap

9 as opposed to 26 in the open source site.

Can you confirm that I will indeed be able to do AES-CBC and RSA-ECB with just these headers ?

Accepted Answer

CommonCrypto is an Apple Open Source C library (no lib file ?) which requires an Objective-C wrapper, hence the CryptoCompatibility sample code.

You’re a bit off in the weeds here:

  • While Common Crypto is open source, the open source code shows a lot of stuff that’s not API. If you’re using Common Crypto in a product, stick with the APIs in your platform SDK.

  • The implementation of Common Crypto is within the System framework, aka libSystem. Xcode automatically links you to that.

  • It’s always been possible to call Common Crypto from Swift.

  • Historically it was tricky to use from Swift because there was no module map, and so the obvious thing, import CommonCrypto, didn’t work. We fixed that a while back. I don’t know if the fix is in Xcode 12, but it’s definitely in all versions of Xcode 13.

  • Having said that, it’s still not easy to use from Swift, because it requires a detailed understanding of how to use C APIs from Swift. Folks who have that experience can use Common Crypto from Swift just fine. If you don’t have that experience, it would be better to start by using it from Objective-C and then work out how to interact with that code from Swift.

  • I wrote CryptoCompatibility long before Swift was a thing, which is why it doesn’t have Swift support.

I already mix C++/Objective-C++ and have a bridging header

Cool. Then do this:

  1. Grab the operation from CryptoCompatibility that best matches your requirements and add its .h and .m files to your product.

  2. Include the .h file in your bridging header.

  3. Use that operation from your Swift code.

All the CryptoCompatibility operations work in terms of types that bridge reasonably well into Swift, like NSData bridging to Data. The same can’t be said for Common Crypto (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you Quinn for reply.

This is what I am in the process of doing at the moment.

However, I have a bit of a doubt about AES in the CryptoCompatibility code.

Would I be right in saying that it can only do AES128 ?

If that is the case, would I be right that I would need to make an interface to CCCryptorCreateWithMode to be able to specify AES256 with CBC ?

I have the impression that this would mean a sequence of calls :

  1. CCCryptorCreateWithMode
  2. CCCryptorUpdate
  3. CCCryptorFinal
  4. CCCryptorRelease

Have I understood this correctly ?

Would I be right in saying that it can only do AES128 ?

No.

You’re being confused by an oddity in AES. AES is a block cypher. In most block cyphers the block size and the key size are the same. That’s not tthe case with AES. In AES there is only one algorithm, which has a block size of 128 bits (kCCAlgorithmAES128). That algorithm supports multiple key sizes (kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256). When folks say AES 256 they mean AES with a 256-bit key. There is no AES 256 algorithm.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

From what I understand, if you use an open-source cryptography library like OpenSSL in the App Store, you will need to get import compliance for the French App Store. This is in addition to the confusing export compliance from US-based Apple. The French form is not required if you use only methods provided by the operating system.

Thankyou Quinn and nk_kennedy, for all the helpful advice you have given. I am seeing clearer now.

Integrating cryptography into a swift app
 
 
Q