Core Concepts and Swift Examples with CryptoKit and CommonCrypto

Security plays a critical role in mobile applications — protecting user data, preventing unauthorized access to sensitive information, and ensuring secure network communication. Even when strong algorithms are used, an incorrect cryptographic approach can leave an application vulnerable.

Within the iOS ecosystem, Apple provides CryptoKit for modern cryptographic needs and CommonCrypto for older, low-level requirements.

In this article, we will cover:

  • the fundamental concepts of cryptography,
  • the main cryptographic operations available in CryptoKit,
  • the differences between symmetric and asymmetric encryption,
  • and essential algorithms — especially AES — using Swift examples.

1. What Is Cryptography?

Cryptography is the practice of transforming data using mathematical algorithms to prevent unauthorized access or modification.

The core goals of cryptography are:

  • Confidentiality Ensuring that data can only be read by authorized parties
  • Integrity Verifying that data has not been altered
  • Authentication Confirming the identity of the sender
  • Non-repudiation Preventing the sender from denying an action they performed

2. CryptoKit vs CommonCrypto

With iOS 13, Apple introduced CryptoKit as a modern cryptography framework.

  • Swift-first API
  • Secure defaults
  • Reduced risk of misuse

📌 CryptoKit should be preferred for new projects. CommonCrypto should only be used for legacy codebases or very specific low-level requirements.

3. Core Operations Provided by CryptoKit

CryptoKit covers the most commonly needed cryptographic operations in iOS applications:

  • Hashing
  • Digital Signature Creation and Verification
  • Data Encryption
  • Key Agreement

4. Hashing

Hash functions transform input data into a fixed-length, irreversible output. Hashing is not encryption.

Common use cases

  • Password storage (server-side)
  • Data integrity verification
  • Cache validation

SHA-256 Example (CryptoKit)

import CryptoKit

let data = Data("hello world".utf8)
let hash = SHA256.hash(data: data)

let hashString = hash.map {
    String(format: "%02x", $0)
}.joined()

print(hashString)

📌 The same input always produces the same hash, but the original data cannot be recovered from it. ⚠️ User passwords should not be hashed directly using SHA-256.

Why SHA-256 Should Not Be Used for Password Storage

Although SHA-256 is a cryptographically secure hash function, it is not suitable for password storage.

The main reason is that SHA-256 is designed to be fast. Modern GPUs can compute billions of SHA-256 hashes per second, making brute-force and dictionary attacks highly effective once a password database is compromised.

Secure password storage requires slow, adaptive hashing algorithms such as bcrypt, scrypt, or Argon2, which significantly increase the cost of offline attacks by design.

📌 In practice, password hashing should always be handled server-side, while iOS applications should transmit passwords securely over TLS and never store or hash them locally.

5. Digital Signatures (Signing & Verification)

Digital signatures are used to prove:

  • that data has not been modified
  • who signed the data

CryptoKit uses Elliptic Curve Cryptography (ECC) with the P-256 curve for this purpose.

Creating a Key Pair

let privateKey = P256.Signing.PrivateKey()
let publicKey = privateKey.publicKey

Signing Data

let message = Data("important message".utf8)
let signature = try privateKey.signature(for: message)

Verifying the Signature

let isValid = publicKey.isValidSignature(signature, for: message)
print(isValid)

📌 Digital signatures are commonly used to validate data received from a backend service.

6. Symmetric vs Asymmetric Encryption

One of the most fundamental distinctions in cryptography is between symmetric and asymmetric encryption.

🔐 Symmetric Encryption

In symmetric encryption:

  • The same key is used for both encryption and decryption.

Key characteristics

  • Very fast
  • Suitable for large amounts of data
  • Key secrecy is critical
  • If the key is compromised, all data can be decrypted

Example algorithm: AES

📌 Ideal for local data, file encryption, and secure caching.

🔑 Asymmetric Encryption

In asymmetric encryption:

  • A public key / private key pair is used

Key characteristics

  • Slower than symmetric encryption
  • No key-sharing problem
  • Ideal for authentication and digital signatures

Example algorithms: RSA, ECC

📌 Not suitable for encrypting large amounts of data.

📌 How It Works in Real Systems

In real-world systems, these approaches are typically combined:

  • Asymmetric encryption → key exchange
  • Symmetric encryption → data transfer

7. Encrypting Data with AES (CryptoKit)

AES is the most widely used symmetric encryption algorithm today. CryptoKit uses AES-GCM, which provides:

  • Encryption
  • Data integrity
  • Authentication

all in a single, secure construction.

Creating a Key

let key = SymmetricKey(size: .bits256)

Encrypting Data

let data = Data("Secret message".utf8)
let sealedBox = try AES.GCM.seal(data, using: key)
let encryptedData = sealedBox.combined!

Decrypting Data

let box = try AES.GCM.SealedBox(combined: encryptedData)
let decryptedData = try AES.GCM.open(box, using: key)

print(String(data: decryptedData, encoding: .utf8)!)

📌 AES keys should be stored securely in the Keychain.

8. Key Agreement

Key agreement allows two parties to derive the same secret key without transmitting it directly. In CryptoKit, this is achieved using ECDH.

let aliceKey = P256.KeyAgreement.PrivateKey()
let bobKey = P256.KeyAgreement.PrivateKey()

let sharedSecret = try aliceKey.sharedSecretFromKeyAgreement(
    with: bobKey.publicKey
)

This shared secret is typically converted into an AES key for symmetric encryption.

9. CommonCrypto and Legacy AES Usage

CommonCrypto:

  • Is C-based
  • Requires manual memory management
  • Has a higher risk of misuse

📌 Therefore:

  • Not recommended for new projects
  • Should only be used when maintaining legacy code
None

11. Real-World Example: Encrypting and Decrypting Text in a SwiftUI App

import SwiftUI
import CryptoKit

struct ContentView: View {
    
    @State private var originalText = "Bu benim gizli notum"
    @State private var encryptedData: Data?
    @State private var decryptedText = ""
    
    var body: some View {
        VStack(spacing: 20) {
            
            Text("Original Text")
                .font(.headline)
            Text(originalText)
            
            Button("Encrypt") {
                do {
                    encryptedData = try encrypt(text: originalText)
                } catch {
                    print("Encrypt error:", error)
                }
            }
            
            if let encryptedData {
                Text("Encrypted Bytes: \(encryptedData.count)")
                    .font(.subheadline)
            }
            
            Button("Decrypt") {
                guard let encryptedData else { return }
                
                do {
                    decryptedText = try decrypt(data: encryptedData)
                } catch {
                    print("Decrypt error:", error)
                }
            }
            
            if !decryptedText.isEmpty {
                Text("Decrypted Text")
                    .font(.headline)
                Text(decryptedText)
                    .foregroundColor(.green)
            }
        }
        .padding()
    }
}

// MARK: - Encryption Helpers

let encryptionKey = SymmetricKey(size: .bits256)

func encrypt(text: String) throws -> Data {
    let data = Data(text.utf8)
    let sealedBox = try AES.GCM.seal(data, using: encryptionKey)
    return sealedBox.combined!
}

func decrypt(data: Data) throws -> String {
    let box = try AES.GCM.SealedBox(combined: data)
    let decryptedData = try AES.GCM.open(box, using: encryptionKey)
    return String(decoding: decryptedData, as: UTF8.self)
}

Conclusion

CryptoKit provides a:

  • Modern
  • Secure
  • Swift-friendly cryptography solution for iOS applications.

In summary:

  • Hash ≠ Encryption
  • AES → data encryption
  • ECC → signatures and key exchange
  • CryptoKit should be preferred over CommonCrypto

For iOS developers, the biggest risk is not using cryptography — it's using cryptography incorrectly.