Hallo mensen, Leo Hier. The topic today is HMAC Key Cryptography in Swift and an example of how to authenticate messages with native Swift.
This is my first post abroad, now writing from the Netherlands! 🎉🎉🎉 I was missing writing here and talking to you all.
Now I’m more or less settled down for a bit and I have time to post a really quick article about iOS and Cryptography. Today will talk about a key derivation function using CryptoKit. This comes in handy when you have to share secrets between two recipients.
The process is simple, we will derive a symmetric key from some info (and that can be random and public for everyone) and after that, we will just create an authentication code to a message so everyone can assure that the message/data is trustworthy.
Let’s code but first…
Painting of The Day
The painting I choose today is Man Writing a Letter (1662-1665), from Gabriël Metsu. Born in 1629 and died in 1667 was a Dutch painter of history paintings, still lifes, portraits, and genre works. He was “a highly eclectic artist, who did not adhere to a consistent style, technique, or one type of subject for long periods”. Only 14 of his 133 works are dated.
I choose it because it is my first post in the Netherlands, so a Dutch painter is more than appropriate. And secondly, the post is talking about how to ensure that the message content wasn’t modified. So a man writing a letter is suitable because in the old days they used to use was and a signed ring to ensure that the content of a letter wasn’t modified from the sender to the receiver.
The Problem – HMAC Key Cryptography in Swift
You want to create a message authentication string using SHA256 and the key creation is based on the same hash function using the HMAC-based Key Derivation Function
Let’s first explain what the HMAC-based Key Derivation Function is. This is just one form of a KDF, Key derived Function. In short, terms is just a function that you use some Data to input and it gives you a pseudorandom symmetric key as output.
A key derivation function (KDF) is a cryptographic hash function that derives one or more secret keys from a secret value such as a main key, a password, or a passphrase using a pseudorandom function. KDFs can be used to stretch keys into longer keys or to obtain keys of a required format, such as converting a group element that is the result of a Diffie–Hellman key exchange into a symmetric key for use with AES. Keyed cryptographic hash functions are popular examples of pseudorandom functions used for key derivation.
Our workflow will be this:
- every interesting part has to know the key input material AND the key generation function, in this case, is HKDF( HMAC-based Key Derivation Function).
- You generate the key using the input material and the HKDF.
- Use the key in an HMAC with any hash function that you want ( in our case SHA256 for both derivation and authentication code creation) to create the authentication code.
- Send the code and the authentication code together for anyone who wants to assert if the message wasn’t modified.
Let’s start creating the symmetric key based on some input.
Creating Symmetric Key from Input Data
First, we need the input material. This should be shared with both ends, this string can and should be public because if not, no one can verify the authentication code later. This is because we are not giving the symmetric key to anyone. This will be done only by sharing the string input material.
let secretPassword = "inputMaterialString".data(using: .utf8)! // Mark 1 let hkdfResultKey = HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: secretPassword), outputByteCount: 151) // Mark 2
With the code above you on Mark 1 we just create Data from a String. This String is exactly what we talk about in the workflow as the “Key Input Material”. So when we talk about sharing the key input material, this is what we are talking about.
Mark 2 is where we use the HKDF CryptoKit Struct to call the deriveKey static function to generate a 151-byte long symmetric Key that we can use to do other cryptography operations such as create an authentication code for any Data. There are two inputs to the function on Mark 2: the first is the data you are using as input material for your key and the second is the size in Bytes of the key you want to generate.
To test if the size is right just print the value divided by 8, because the value is in bits:
print("The generated key size (in bytes): ",hkdfResultKey.bitCount/8)
So yeah the most difficult part is gone, now you can use your symmetric as you want. Today we will use it to create an authentication code that you can use to ensure that the message didn’t change.
Let’s create a message to be verified and the authentication code:
let trustfulMessage = "The message that would be verified by the authentication code".data(using: .utf8)! let authenticationCode = HMAC<SHA256>.authenticationCode(for: trustfulMessage, using: hkdfResultKey) // Mark 2 print("\(authenticationCode.description)")
The result is:
The code above demonstrates how you can generate an authentication code in Mark 2 and you just need to input a Data struct and the key we generate above.
So now if you want to check if the message was modified, you can use the input material to generate a key like us and generate the authentication code. As no one else will know how to derive the key, we are safe!
Very cool isn’t it?
Full Code Example
The whole code you can check below and test in your playgrounds:
import CryptoKit let secretPassword = "inputMaterialString".data(using: .utf8)! let hkdfResultKey = HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: secretPassword), outputByteCount: 151) print("The generated key size (in bytes): ",hkdfResultKey.bitCount/8) let trustfulMessage = "The message that would be verified by the authentication code".data(using: .utf8)! let authenticationCode = HMAC<SHA256>.authenticationCode(for: trustfulMessage, using: hkdfResultKey) print("\(authenticationCode.description)")
And that’s it!
Summary – HMAC Key Cryptography in Swift
There’s a way to derive keys using CryptoKit from almost every kind of input. This way you can create very complex cryptography operations with just a few steps.
That’s all my people, I hope you liked reading this article as much as I enjoyed writing it. If you want to support this blog you can Buy Me a Coffee or leave a comment saying hello. You can also sponsor posts and I’m open to
freelance writing! You can reach me on LinkedIn or Twitter and send me an e-mail through the contact page.
Thanks for reading and… That’s all folks.