Криптография в 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 (Galois/Counter Mode).
Пример шифрования и расшифровки с 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 для работы с RSA используется Security.framework и SecKey.
Пример генерации ключей и шифрования 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,
&error
) else {
print("Ошибка шифрования: \(error!.takeRetainedValue())")
return nil
}
return ciphertext as Data
}
4. HMAC (Аутентификация сообщений)
HMAC (Hash-based Message Authentication Code) позволяет проверить подлинность и целостность сообщения с использованием секретного ключа.
Пример HMAC-SHA256
import CommonCrypto
func hmacSHA256(key: String