Cryptography in Swift (iOS/macOS): Encryption and Hashing

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Cryptography in Swift (iOS/macOS): Encryption and Hashing



In modern iOS and macOS development, data security is a critical aspect. Swift provides powerful built-in tools for cryptography, ranging from the low-level CommonCrypto (C-API) to the modern framework CryptoKit (iOS 13+/macOS 10.15+). In this article, we will cover the main encryption and hashing methods available to a Swift developer.



1. Hashing

Hashing is a one-way transformation of data into a fixed-length string. It is used for data integrity verification and password storage (with salt).



Example with CryptoKit (SHA-256)

import CryptoKit

func hashSHA256(_ input: String) -> String { let inputData = Data(input.utf8) let hashed = SHA256.hash(data: inputData) return hashed.compactMap { String(format: "%02x", $0) }.joined()}

// Usagelet hash = hashSHA256("Hello, Swift!")print("SHA-256: \\(hash)")// Output: 8e3a... (64 characters)


Example with CommonCrypto (MD5, deprecated)

Note: MD5 is not recommended for security but can be used for integrity checks.

import CommonCrypto

func md5Hash(_ input: String) -> String { let data = Data(input.utf8) var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH)) data.withUnsafeBytes { bytes in _ = CC_MD5(bytes.baseAddress, CC_LONG(data.count), &digest) } return digest.map { String(format: "%02x", $0) }.joined()}


2. Symmetric Encryption (AES-GCM)

Symmetric encryption uses a single key for both encryption and decryption. CryptoKit provides a secure implementation of AES-GCM (Galois/Counter Mode).



Example of encryption and decryption with CryptoKit

import CryptoKit

func encryptAESGCM(plaintext: String, key: SymmetricKey) throws -> Data { let plaintextData = Data(plaintext.utf8) let sealedBox = try AES.GCM.seal(plaintextData, using: key) return sealedBox.combined! // combined = nonce + ciphertext + tag}

func decryptAESGCM(ciphertext: Data, key: SymmetricKey) throws -> String { let sealedBox = try AES.GCM.SealedBox(combined: ciphertext) let decryptedData = try AES.GCM.open(sealedBox, using: key) return String(data: decryptedData, encoding: .utf8)!}

// Usagelet key = SymmetricKey(size: .bits256) // 256-bit keylet encrypted = try encryptAESGCM(plaintext: "Secret message", key: key)let decrypted = try decryptAESGCM(ciphertext: encrypted, key: key)print("Decrypted: \\(decrypted)")


3. Asymmetric Encryption (RSA)

Asymmetric encryption uses a key pair: a public key (for encryption) and a private key (for decryption). In iOS/macOS, Security.framework and SecKey are used for working with RSA.



Example of RSA key generation and encryption

import Security

func generateRSAKeyPair() -> (privateKey: SecKey, publicKey: SecKey)? { let attributes: [String: Any] = [ kSecAttrKeyType as String: kSecAttrKeyTypeRSA, kSecAttrKeySizeInBits as String: 2048, kSecPrivateKeyAttrs as String: [kSecAttrIsPermanent as String: false], kSecPublicKeyAttrs as String: [kSecAttrIsPermanent as String: false] ] guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, nil) else { return nil } let publicKey = SecKeyCopyPublicKey(privateKey)! return (privateKey, publicKey)}

func encryptRSA(plaintext: String, publicKey: SecKey) -> Data? { let plaintextData = Data(plaintext.utf8) var error: Unmanaged<CFError>? guard let ciphertext = SecKeyCreateEncryptedData( publicKey, .rsaEncryptionPKCS1, plaintextData as CFData,

Recommendations