Leonardo Maia Pugliese
Holy Swift

Holy Swift

Cryptographic Keys and Swift

Cryptographic Keys and Swift

Armor your data with cryptography

Leonardo Maia Pugliese's photo
Leonardo Maia Pugliese
·Dec 29, 2021·

8 min read

Subscribe to my newsletter and never miss my upcoming articles

Today we will introduce a very nice theme about Cryptographic Keys. iOS is heavily secure based on cryptography, that Apple introduces in iPhone 5S versions and above a dedicated subsystem (mix of hardware and software) called Secure Enclave.

For us, iOS developers, it's very important to know the basic concepts about app security because we don't want leak all of our user data to outside world. When talking about security it's always a premise that our system will as safe as possible to corroborate in our apps reliability efforts.

We will study what are cryptographic keys, their types and how iOS CryptoKit framework help us creating them and using them.

Let's code, but first...

The Painting

The painting is a 1505 masterpiece called St. George and the Dragon from the painter Raffaello Sanzio da Urbino. He is considered one of great master painters, Raphael was an Italian painter and architect in the High Renaissance. Raphael, along with Michelangelo and Leonardo da Vinci, are considered the great trinity of master painters of the High Renaissance period. He was a prolific artist, and despite death at the young age of 37, has a considerable body of work to study.

I chose this painting because the knight is using a shiny armor, and that is the knight protection against the dragon as same as cryptography can protect us from malicious attacks.

The Problem

You were asked to create an app that generate various kinds of cryptographic keys.

First let's start with the core concepts about Cryptograph Keys. First let's see it's definition, after we will study different types of keys, and finally how to implement those in your iOS applications.

Cryptographic Keys Definition

The dictionary definition is:

Secret value used by a computer together with a complex algorithm to encrypt and decrypt messages. Since confidential messages might be intercepted during transmission or travel over public networks, they require encryption so that they will be meaningless to third parties in order to maintain confidentiality. The intended recipient, and only the recipient, must also be able to decrypt them. If someone encrypts a message with a key, only someone else with a matching key should be able to decrypt the message.

This definition is the most basic modern use case for cryptographic keys. Since internet is a continuous information exchange, maintaining confidentiality is crucial for all participants. It's very important that no ones but you and the receiver of your are able to check the content of the messages you exchanges.

When you think about cryptographic keys you can also think in real keys. You front door key open and close your house for whoever has a copy of it. Therefore it's very important only people you authorise has the key for your house.

iOS use the Secure Enclave, that is a hardware plus software solution for iPhones since iPhone 5S. The Secure Enclave is responsible among other things to cryptograph all private data inside your iPhone. Some of your most used day-to-day features are handled by the it, for example:

  • Passcode change
  • Enabling or disabling Touch ID or Face ID
  • Adding or removing a Touch ID fingerprint or Face ID face
  • Touch ID or Face ID reset
  • Adding or removing an Apple Pay card
  • Erase All Content and Settings

Now you can visualise how important is the role of the Secure Enclave in our lives, right? Anyone could unlock your iPhone if Face ID doesn't work well. Or worst, could use your Apple Pay to pay unwanted things or delete everything from your iPhone with a priceless loss of your digital content.

In summary , cryptography key is an input parameter to a cryptographic algorithm or cipher function, which uniquely encodes plaintext (messages or other information) into ciphertext during encryption, and vice versa during decryption.

Cryptographic Keys Types - Symmetric and Asymmetric

Cryptographic keys can be divided in two groups. The symmetric keys and asymmetric keys. All systems over the world use one or more likely both techniques to ensure it protection.

Let's explain both keys using an example of encrypting a message.

If you use a symmetric key to encrypt a message and send that message, the receiver will need the same key to decrypt it. This way you need somehow to exchange this key with the other participant so it can completely decrypt the message. This can be a problem/disadvantage when you have no safe means on exchanging the symmetric key. Symmetric key advantages are the fast computing encrypt/decrypt process and it's easy to create new symmetric keys.

On the other hand, the asymmetric keys are a pair of keys: the public key and the private key. Different from symmetric key techniques each key only does one cryptic operation. The public key only encrypt and the private key only decrypt data.

Going back to our example, in this case you will encrypt the message with the public key and the receiver will decrypt the message with the private key. You can do most of your applications with asymmetric keys since the public key can be freely shared around and the message won't be able to be decrypted. If you need some private data from other source, just create an asymmetric key pair(public and private key) and send the public key to it, after that the other source will use the public key to encrypt the data and send back to you, and finally you can decrypt that data with your private key. The disadvantages of public/private key algorithms are that generate keys are most expensive and most of the time you have to keep each of the private keys stored for each public key sent.

To sum up everything about both of the Keys types. Symmetric keys encryption techniques uses a single symmetric key for both process of encryption and decryption, whereas asymmetric key(public and private) techniques use two different but related keys for encryption and decryption.

Ephemeral vs Static keys

The other trait about keys is related to a concept called crypto-period or lifetime. Cryptographic keys may be static (built for long term) or ephemeral (built to be used for a single session).

Static means the encrypt and decrypt functions are only valid throughout a longer period of time, for example one month or 2 hours. However you have to think that longer the period you are using it, more susceptible it is to be attacked. It is always important to keep in mind the replacement of the keys when they are static, this is called cycling.

The Ephemeral ones are the safest a key can be. It has a single use and it's gone. It's impossible to revert or trying to recover that. When you use it, it's gone forever.

Apple doesn't support this type of key natively yet but we can create our own key manager to handle that for us. You just need to create something that each time that do the decrypt operation, it start a cycling process of the keys.

For now, this is enough theory about cryptographic keys. Let's implement them in the Playgrounds!

Implementation

First let's see an example of symmetric key encryption, you have to import CryptoKit to follow this example:

        let messageData = "Go Go Power Rangers!".data(using: .utf8)! // mark 1
        let symmetricKey = CryptoKit.SymmetricKey.init(size: .bits256) // mark 2
        print("Symmetric Key -> \(symmetricKey)")

        let encryptedSealedBox = try! AES.GCM.seal(messageData, using: symmetricKey, nonce: nil) // mark 3
        print("Ecrypted Sealed Box Base64 text -> \(encryptedSealedBox.ciphertext.base64EncodedString())")

        // this decryption usually occurs in other system, so you will have to send somehow the symmetric key to it.
        let decriptSealedBox = try! AES.GCM.open(encryptedSealedBox, using: symmetricKey) // mark 4
        print("Text decrypted -> ",String(data: decriptSealedBox, encoding: .utf8)!)

Explaining each mark:

  1. We have to transform any object we have into data to be able to use it in the CryptoKit framework. In this case we are transforming the String "Go Go Power Rangers!"
  2. Mark 2 is where we create the random generated symmetric key. This key will be used in both process of encrypt and decrypt the messageData
  3. We are using the AES algorithm to encrypt the messageData with the symmetric key we created in step 2 and the result is a SealedBox object, with contains the encrypted data among other things.
  4. Finally we open the sealed box, aka decrypt our message using the same key created in the step 2.

Did you noticed that step 3 and step 4 we used the same key? This is way is a symmetric algorithm, we use the same key to do all the cryptograph operations.

The final result in the console is:

Screenshot 2021-12-29 at 08.53.24.png

Now, let's explore an example of asymmetric cryptography.

Copy paste the code below:

// Generate salt
        let randomSymmetricKey = SymmetricKey(size: .bits256) 
        let salt = randomSymmetricKey.withUnsafeBytes { Data($0) }

// Mark 1
        let playerAPrivateKey = P521.KeyAgreement.PrivateKey()
        let playerAPublicKey = playerAPrivateKey.publicKey
        let playerBPrivateKey = P521.KeyAgreement.PrivateKey()
        let playerBPublicKey = playerBPrivateKey.publicKey

        // Mark 2 
        let playerASharedSecret = try! playerAPrivateKey.sharedSecretFromKeyAgreement(with: playerBPublicKey)
        let playerASymmetricKey = playerASharedSecret.hkdfDerivedSymmetricKey(using: SHA256.self, salt: salt, sharedInfo: Data(), outputByteCount: 32)

        // player B gets the agreement with player A
        let playerBSharedSecret = try! playerBPrivateKey.sharedSecretFromKeyAgreement(with: playerAPublicKey)
        let playerBSymmetricKey = playerBSharedSecret.hkdfDerivedSymmetricKey(using: SHA256.self, salt: salt, sharedInfo: Data(), outputByteCount: 32)


// from here it's the same as the symmetric example but here we will prove that you can use different derived keys to encrypt and decrypt the message

        let messageData = "Go Go Power Rangers!".data(using: .utf8)! 

        let encryptedSealedBox = try! AES.GCM.seal(messageData, using: playerASymmetricKey, nonce: nil)
        print("player A sent Ecrypted data derived key text -> \(encryptedSealedBox.ciphertext.base64EncodedString())")

        let decriptSealedBox = try! AES.GCM.open(encryptedSealedBox, using: playerBSymmetricKey)
        print("Player B received the Text decrypted with player B derived key -> ",String(data: decriptSealedBox, encoding: .utf8)!)

Imagine that you have two players, player A and player B. They exchange public keys with each other and created derived symmetric keys from it (of course, the salt should be the same). And them they can exchange crypto messages that both parties will understand.

Screenshot 2021-12-29 at 09.37.05.png

And that's it for today!

Summary

Today we explore an introduction on keys in iOS development and how you can leverage your apps security with an encryption technique.

That's all my people, I hope you liked as I enjoyed write this article. If you want to support this blog you can Buy Me a Coffee or just leave a comment saying hello. You can also sponsor posts and I'm open to writing freelancing! Just reach me in LinkedIn or Twitter for details.

Thanks for the reading and... That's all folks.

credit: image

Did you find this article valuable?

Support Leonardo Maia Pugliese by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
 
Share this