面试题答案
一键面试设计思路
- 类的定义:创建一个自定义类,用于处理数据的加密和解密,同时模拟IO流功能。
- 加密算法选择:选择AES加密算法,Swift中可以使用
CryptoKit
库来实现AES加密。 - 成员变量:包含加密密钥、初始化向量(IV)等用于加密和解密的必要参数。
- 方法:设计加密方法、解密方法,以及模拟IO流的读取和写入方法。
- 结合系统操作:在文件操作或网络操作中,在写入数据前调用加密方法,在读取数据后调用解密方法。
成员变量
- 密钥(Key):用于加密和解密的关键参数。
- 初始化向量(IV):增加加密安全性,通常长度固定。
方法
- 加密方法:接受原始数据,使用AES算法进行加密并返回加密后的数据。
- 解密方法:接受加密后的数据,使用AES算法进行解密并返回原始数据。
- 模拟写入方法:接受数据,先加密再进行实际的文件或网络写入操作。
- 模拟读取方法:进行实际的文件或网络读取操作,读取后解密并返回数据。
关键代码片段
import CryptoKit
import Foundation
class SecureIOStream {
let key: SymmetricKey
let iv: AES.GCM.Nonce
init(key: SymmetricKey, iv: AES.GCM.Nonce) {
self.key = key
self.iv = iv
}
func encrypt(data: Data) throws -> Data {
let sealedBox = try AES.GCM.seal(data, using: key, nonce: iv)
return sealedBox.combined
}
func decrypt(data: Data) throws -> Data {
let sealedBox = try AES.GCM.SealedBox(combined: data)
return try AES.GCM.open(sealedBox, using: key, nonce: iv)
}
func writeToFile(data: Data, filePath: String) throws {
let encryptedData = try encrypt(data: data)
try encryptedData.write(to: URL(fileURLWithPath: filePath))
}
func readFromFile(filePath: String) throws -> Data {
let encryptedData = try Data(contentsOf: URL(fileURLWithPath: filePath))
return try decrypt(data: encryptedData)
}
}
与系统操作结合示例
// 创建密钥和IV
let key = SymmetricKey(size: .bits256)
let iv = try! AES.GCM.Nonce(data: Data(count: AES.GCM.Nonce.byteCount))
let secureStream = SecureIOStream(key: key, iv: iv)
let originalData = "Hello, Secure World!".data(using: .utf8)!
// 写入文件
try secureStream.writeToFile(data: originalData, filePath: "/tmp/secureData")
// 读取文件
let decryptedData = try secureStream.readFromFile(filePath: "/tmp/secureData")
print(String(data: decryptedData, encoding: .utf8)!)
在网络操作中,类似地,在发送数据前调用encrypt
方法,在接收数据后调用decrypt
方法。例如,使用URLSession
进行网络请求:
func sendDataOverNetwork(data: Data, url: URL) async throws {
let encryptedData = try secureStream.encrypt(data: data)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = encryptedData
let (_, _) = try await URLSession.shared.data(for: request)
}
func receiveDataFromNetwork(url: URL) async throws -> Data {
let (data, _) = try await URLSession.shared.data(from: url)
return try secureStream.decrypt(data: data)
}