Swift(iOS/macOS)中的密码学:加密与哈希

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Swift(iOS/macOS)中的密码学:加密与哈希



在现代 iOS 和 macOS 开发中,数据安全是至关重要的方面。Swift 提供了强大的内置密码学工具,从底层的 CommonCrypto(C-API)到现代的 CryptoKit 框架(iOS 13+/macOS 10.15+)。在本文中,我们将介绍 Swift 开发者可用的主要加密和哈希方法。



1. 哈希(Hashing)

哈希是将数据单向转换为固定长度字符串的过程。它用于验证数据完整性和存储密码(加盐)。



使用 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()}

// 使用let hash = hashSHA256("Hello, Swift!")print("SHA-256: \\(hash)")// 输出:8e3a...(64 个字符)


使用 CommonCrypto 的示例(MD5,已弃用)

注意:MD5 不推荐用于安全目的,但可用于完整性校验。

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. 对称加密(AES-GCM)

对称加密使用同一个密钥进行加密和解密。CryptoKit 提供了安全的 AES-GCM(伽罗瓦/计数器模式)实现。



使用 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)!}

// 使用let key = SymmetricKey(size: .bits256) // 256 位密钥let encrypted = try encryptAESGCM(plaintext: "秘密消息", key: key)let decrypted = try decryptAESGCM(ciphertext: encrypted, key: key)print("解密结果:\\(decrypted)")


3. 非对称加密(RSA)

非对称加密使用一对密钥:公钥(用于加密)和私钥(用于解密)。在 iOS/macOS 中,使用 Security.framework 和 SecKey 进行 RSA 操作。



RSA 密钥生成和加密示例

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,

推荐