Criptografía en Swift (iOS/macOS): cifrado y hashing
En el desarrollo moderno para iOS y macOS, la seguridad de los datos es una de las prioridades clave. Apple proporciona potentes herramientas integradas para la protección criptográfica: desde el hashing simple hasta el cifrado asimétrico. En este artículo, veremos cómo usar CryptoKit (el framework recomendado desde iOS 13 / macOS 10.15) y el clásico CommonCrypto para resolver tareas típicas: cifrado, hashing y autenticación de datos.
Conceptos básicos
Antes de pasar al código, aclaremos los términos:
- Cifrado simétrico — se usa una misma clave tanto para cifrar como para descifrar (por ejemplo, AES).
- Cifrado asimétrico — un par de claves: pública (para cifrar) y privada (para descifrar).
- Hashing — transformación irreversible de datos en una cadena de longitud fija (SHA-256).
- HMAC — código de autenticación de mensaje basado en hash utilizando una clave.
1. Hashing con CryptoKit
CryptoKit es un framework moderno de Swift que hace que la criptografía sea simple y segura. Para el hashing se utiliza la estructura SHA256.
import CryptoKit
func hashString(_ input: String) -> String { let inputData = Data(input.utf8) let hashed = SHA256.hash(data: inputData) return hashed.compactMap { String(format: "%02x", $0) }.joined()}
// Ejemplo de usolet password = "MySecurePass123"let hash = hashString(password)print("Hash SHA-256: \\(hash)")También están disponibles SHA384, SHA512 y SHA1 (este último solo por compatibilidad).
2. HMAC (autenticación de mensaje)
HMAC agrega una clave al hash, lo que protege contra la falsificación. En CryptoKit esto se implementa mediante HMAC especificando el algoritmo:
import CryptoKit
func hmacSHA256(key: SymmetricKey, message: String) -> String { let messageData = Data(message.utf8) let code = HMAC<SHA256>.authenticationCode(for: messageData, using: key) return code.compactMap { String(format: "%02x", $0) }.joined()}
// Generación de clavelet key = SymmetricKey(size: .bits256)let hmac = hmacSHA256(key: key, message: "Mensaje importante")print("HMAC: \\(hmac)")3. Cifrado simétrico (AES-GCM)
AES-GCM es un modo de cifrado moderno que proporciona tanto confidencialidad como autenticación (evita la manipulación de datos). CryptoKit lo soporta de forma nativa.
import CryptoKit
func encryptAESGCM(plainText: String, key: SymmetricKey) throws -> Data { let plainData = Data(plainText.utf8) let sealedBox = try AES.GCM.seal(plainData, using: key) return sealedBox.combined! // combined = nonce + ciphertext + tag}
func decryptAESGCM(encryptedData: Data, key: SymmetricKey) throws -> String { let sealedBox = try AES.GCM.SealedBox(combined: encryptedData) let decryptedData = try AES.GCM.open(sealedBox, using: key) return String(data: decryptedData, encoding: .utf8)!}
// Ejemplolet key = SymmetricKey(size: .bits256)let originalText = "Datos secretos"
do { let encrypted = try encryptAESGCM(plainText: originalText, key: key) let decrypted = try decryptAESGCM(encryptedData: encrypted, key: key) print("Descifrado: \\(decrypted)")} catch { print("Error: \\(error)")}Importante: combined incluye todo lo necesario para el descifrado (nonce, ciphertext, tag). Guárdelo junto con los datos cifrados.
4. Cifrado asimétrico (RSA) mediante CommonCrypto
Para RSA, CryptoKit no proporciona una API directa, pero se puede usar Security.framework y CommonCrypto