iOS閱后即焚功能實現步驟
一、功能設計要點
- 消息類型支持:文本、圖片、視頻、音頻等。
- 銷毀觸發條件:
- 接收方首次打開消息后啟動倒計時。
- 消息存活時間可配置(如5秒、1分鐘)。
- 安全要求:
- 端到端加密(E2EE)。
- 防止截圖/錄屏(檢測+警告)。
- 服務器不留存可解密的消息內容。
二、技術實現方案
1. 消息加密與傳輸
- 加密算法選擇:
// 使用CryptoKit進行AES-GCM加密 import CryptoKit func encryptMessage(_ message: Data, key: SymmetricKey) -> Data? {let sealedBox = try? AES.GCM.seal(message, using: key)return sealedBox?.combined }
- 密鑰管理:
- 使用Diffie-Hellman算法動態生成會話密鑰。
- 密鑰存儲于iOS Keychain(敏感數據保護級別)。
2. 消息存儲與生命周期管理
- 本地存儲結構:
struct EphemeralMessage {let messageId: Stringvar content: Data // 加密后的數據var status: MessageStatus // .sent / .opened / .expiredvar destroyTime: Date? }
- 自動銷毀邏輯:
// 消息打開時啟動定時器 func startDestructionTimer(for messageId: String, duration: TimeInterval) {DispatchQueue.global().asyncAfter(deadline: .now() + duration) {deleteMessageFromLocalAndServer(messageId)} }
3. 防截圖/錄屏機制
- 截圖檢測:
NotificationCenter.default.addObserver(self,selector: #selector(didTakeScreenshot),name: UIApplication.userDidTakeScreenshotNotification,object: nil )@objc func didTakeScreenshot() {// 立即銷毀當前顯示的消息forceDestroyActiveMessage()// 向服務器發送截圖警報reportScreenshotEvent() }
- 錄屏檢測(iOS 11+):
if UIScreen.main.isCaptured {showAlert("檢測到屏幕錄制,消息已銷毀")destroyActiveMessage() }
4. 媒體內容保護
- 圖片防保存:
class SecureImageView: UIImageView {override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {// 禁用長按菜單return false} }
- 視頻DRM(FairPlay):
let contentKeySession = AVContentKeySession(keySystem: .fairPlayStreaming) contentKeySession.setDelegate(self, queue: DispatchQueue.main)
5. 服務器端實現
- 消息元數據表結構:
CREATE TABLE ephemeral_messages (message_id VARCHAR(64) PRIMARY KEY,sender_id VARCHAR(64),receiver_id VARCHAR(64),encrypted_key TEXT, // 加密后的會話密鑰status ENUM('sent','delivered','opened','expired'),expire_at TIMESTAMP );
- 自動清理任務:
# 每小時清理過期消息 DELETE FROM ephemeral_messages WHERE expire_at < NOW();
三、關鍵代碼示例
1. 端到端加密流程
// 發送方
let plainText = "Secret Message".data(using: .utf8)!
let sessionKey = SymmetricKey(size: .bits256)
let encryptedMessage = encryptMessage(plainText, key: sessionKey)// 使用接收方公鑰加密會話密鑰
let receiverPublicKey = loadPublicKeyFromKeychain()
let encryptedKey = try RSA.encrypt(sessionKey, publicKey: receiverPublicKey)// 將encryptedMessage + encryptedKey發送至服務器
2. 消息查看頁面控制器
class MessageViewController: UIViewController {var message: EphemeralMessage!private var destructionTimer: Timer?override func viewDidAppear(_ animated: Bool) {super.viewDidAppear(animated)// 僅首次打開時觸發if message.status == .delivered {startDestructionTimer()updateMessageStatus(.opened)}}private func startDestructionTimer() {destructionTimer = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { [weak self] _ inself?.destroyMessage()}}private func destroyMessage() {// 模糊化內容contentView.applyBlurEffect()// 刪除本地和服務器數據EphemeralMessageManager.shared.delete(messageId: message.messageId)}
}
四、優化與注意事項
-
性能優化:
- 使用
NSCache
緩存已解密內容,避免重復解密開銷。 - 預生成加密密鑰池,減少加密延遲。
- 使用
-
安全增強:
- 實現Perfect Forward Secrecy(PFS),每次會話使用獨立密鑰。
- 定期更換密鑰輪換策略(如每24小時)。
-
法律合規:
- 在隱私政策中明確說明消息銷毀機制。
- 配合執法需求保留元數據(不包含消息內容)。
-
用戶體驗:
- 顯示銷毀倒計時動畫:
let circleLayer = CAShapeLayer() let animation = CABasicAnimation(keyPath: "strokeEnd") animation.fromValue = 1.0 animation.toValue = 0.0 animation.duration = 5.0 circleLayer.add(animation, forKey: "destructionCountdown")
- 顯示銷毀倒計時動畫:
五、測試用例
測試場景 | 預期結果 |
---|---|
接收方未讀消息超過TTL | 服務器自動刪除消息 |
發送方撤回未讀消息 | 消息從服務器和接收端徹底移除 |
接收方嘗試截屏 | 觸發立即銷毀并通知發送方 |
設備離線時消息過期 | 重新聯網后同步刪除狀態 |
多設備登錄同一賬號 | 所有設備同步銷毀狀態 |
通過以上技術方案,可實現高安全性的iOS閱后即焚功能,平衡用戶體驗與數據隱私保護需求。