Swift (iOS/macOS) 中的密码学:加密与哈希
在现代 iOS 和 macOS 开发中,数据安全是首要任务之一。Apple 提供了强大的内置加密保护工具:从简单的哈希到非对称加密。本文将介绍如何使用 CryptoKit(自 iOS 13 / macOS 10.15 起推荐的框架)和经典的 CommonCrypto 来解决典型任务:加密、哈希和数据认证。
基本概念
在进入代码之前,我们先了解一些术语:
- 对称加密 — 使用同一个密钥进行加密和解密(例如 AES)。
- 非对称加密 — 使用一对密钥:公钥(用于加密)和私钥(用于解密)。
- 哈希 — 将数据不可逆地转换为固定长度的字符串(SHA-256)。
- HMAC — 基于哈希的密钥消息认证码。
1. 使用 CryptoKit 进行哈希
CryptoKit 是一个现代 Swift 框架,使加密变得简单且安全。哈希使用 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()}
// 使用示例let password = "MySecurePass123"let hash = hashString(password)print("SHA-256 哈希: \\(hash)")此外还支持 SHA384、SHA512 和 SHA1(后者仅用于兼容性)。
2. HMAC(消息认证)
HMAC 向哈希添加密钥,防止篡改。在 CryptoKit 中通过 HMAC 指定算法实现:
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()}
// 生成密钥let key = SymmetricKey(size: .bits256)let hmac = hmacSHA256(key: key, message: "重要消息")print("HMAC: \\(hmac)")3. 对称加密(AES-GCM)
AES-GCM 是一种现代加密模式,同时提供机密性和认证(防止数据篡改)。CryptoKit 原生支持该模式。
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)!}
// 示例let key = SymmetricKey(size: .bits256)let originalText = "机密数据"
do { let encrypted = try encryptAESGCM(plainText: originalText, key: key) let decrypted = try decryptAESGCM(encryptedData: encrypted, key: key) print("解密结果: \\(decrypted)")} catch { print("错误: \\(error)")}重要提示: combined 包含解密所需的所有内容(nonce、ciphertext、tag)。请将其与加密数据一起存储。
4. 通过 CommonCrypto 实现非对称加密(RSA)
对于 RSA,CryptoKit 不提供直接 API,但可以使用 Security.framework 和 CommonCrypto