CryptoKit in SwiftUI

CryptoKit in SwiftUI

A tutorial on Password Encryption

·

4 min read

Security is a crucial aspect of mobile app development. In iOS app development, encrypting user passwords is an important step to ensure the protection of user data. In this blog post, we'll show you how to encrypt passwords in SwiftUI.

The code in this post is available here.

Why Encrypt Passwords?

Encrypting passwords is essential because it ensures that the user's sensitive data remains safe in case of a security breach. When a user creates an account in your app, they typically choose a password that they can remember easily. However, if that password is not encrypted, it can be easily stolen by malicious actors. Encrypting the password makes it much more difficult for attackers to obtain and use.

Choosing an Encryption Algorithm

There are many encryption algorithms available, but not all of them are suitable for password encryption. A common algorithm used for password encryption is bcrypt. Bcrypt is a slow hashing algorithm that is designed specifically for password storage. It is computationally expensive, which makes brute-force attacks much more difficult.

SwiftUI does not have built-in support for bcrypt, but there are libraries available that make it easy to use. One popular library is called CryptoKit.

Using CryptoKit to Encrypt Passwords

To use CryptoKit to encrypt passwords, we'll start by importing the library in our Swift file:

import CryptoKit

Next, we'll create a function that will take a password string as input and return an encrypted password string:

func encryptPassword(password: String) -> String {
    let salt = "mysalt"
    let saltedPassword = password + salt

    guard let saltedPasswordData = saltedPassword.data(using: .utf8) else {
        return ""
    }

    let hashedPassword = SHA256.hash(data: saltedPasswordData)
    let hashedPasswordString = hashedPassword.compactMap { String(format: "%02x", $0) }.joined()

    return hashedPasswordString
}

In this code, we're using the SHA256 hashing function from CryptoKit to hash the salted password string. We're then converting the hashed data to a hexadecimal string and returning it.

Note that we're using a salt value to increase the security of our password encryption. The salt value is a random string that is added to the password before it is hashed. This makes it much more difficult for attackers to crack passwords using precomputed hash tables.

Using the Encrypt Password Function in SwiftUI

Now that we have our encryptPassword function, we can use it in our SwiftUI views. Let's create a simple view with a text field for the user to enter their password, and a button to encrypt the password.

struct ContentView: View {
    @State var password: String = ""
    @State var encryptedPassword: String = ""

    var body: some View {
        VStack {
            TextField("Password", text: $password)

            Button("Encrypt Password") {
                encryptedPassword = encryptPassword(password: password)
            }

            Text("Encrypted Password: \(encryptedPassword)")
        }
    }
}

In this code, we're using the @State property wrapper to create two state variables: password and encryptedPassword. We're creating a text field for the user to enter their password, and a button to encrypt the password using our encryptPassword function. We're then displaying the encrypted password in a Text view.

Redaction

After implementing the encryption functionalities, we can improve our logic by adding a button to hide the encrypted password with redaction. For more about Redaction, check my previous post here.

struct ContentView: View {
    @State var password: String = ""
    @State var encryptedPassword: String = ""
    @State var hideEncryptedPassword: Bool = false

    var body: some View {
        VStack {
            TextField("Password", text: $password)

            Button("Encrypt Password") {
                encryptedPassword = encryptPassword(password: password)
            }

            Text("Encrypted Password:")
                .bold()
            Group {
                if hideEncryptedPassword {
                    Text("\(encryptedPassword)")
                        .redacted(reason: .placeholder)
                } else {
                    Text("\(encryptedPassword)")
                }
            }
            Button(hideEncryptedPassword ? "Show" : "Hide") {
                hideEncryptedPassword.toggle()
            }
        }
    }
}

In the example above, we added a @State property of type Bool to indicate if the encrypted password text is hidden. Then we replaced the encrypted password text with a Group which is conditional to redact the text if hideEncryptedPassword is true. And we added another button to toggle the boolean value of hideEncryptedPassword.

UI Enhancement

And finally, we can make some UI Enhancement by adding borders, frames, bolding and / or colors to our text field and buttons.


struct ContentViewEnhanced: View {
    @State var password: String = ""
    @State var encryptedPassword: String = ""
    @State var hideEncryptedPassword: Bool = false
    var body: some View {
        VStack {
            TextField("Password", text: $password)
                .frame(width: 200, height: 40, alignment: .center)
                .border(.black)
            Button("Encrypt") {
                encryptedPassword = encryptPassword(password: password)
            }
            .bold()
            .foregroundColor(.white)
            .frame(width: 200, height: 40, alignment: .center)
            .background(Color.blue.cornerRadius(10))
            Text("Encrypted Password:")
                .bold()
            Group {
                if hideEncryptedPassword {
                    Text("\(encryptedPassword)")
                        .redacted(reason: .placeholder)
                } else {
                    Text("\(encryptedPassword)")
                }
            }
            Button(hideEncryptedPassword ? "Show" : "Hide") {
                hideEncryptedPassword.toggle()
            }
            .bold()
            .foregroundColor(.white)
            .frame(width: 200, height: 40, alignment: .center)
            .background(Color.blue.cornerRadius(10))
        }
        .padding(.horizontal)
    }
}

And that’s all of today’s post. I hope it helps and let me know if it is by leaving a comment. Don’t forget to subscribe to my newsletter if you’d like to receive posts like this via email.

I’ll see you in the next post!