SecureMessenger.swift 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. // LoopFollow
  2. // SecureMessenger.swift
  3. import CryptoSwift
  4. import Foundation
  5. import Security
  6. struct SecureMessenger {
  7. private let sharedKey: [UInt8]
  8. init?(sharedSecret: String) {
  9. guard let secretData = sharedSecret.data(using: .utf8) else {
  10. return nil
  11. }
  12. sharedKey = Array(secretData.sha256())
  13. }
  14. private func generateSecureRandomBytes(count: Int) -> [UInt8]? {
  15. var bytes = [UInt8](repeating: 0, count: count)
  16. let status = SecRandomCopyBytes(kSecRandomDefault, count, &bytes)
  17. return status == errSecSuccess ? bytes : nil
  18. }
  19. func encrypt<T: Encodable>(_ object: T) throws -> String {
  20. let dataToEncrypt = try JSONEncoder().encode(object)
  21. guard let nonce = generateSecureRandomBytes(count: 12) else {
  22. throw NSError(domain: "SecureMessenger", code: 500, userInfo: [NSLocalizedDescriptionKey: "Failed to generate secure random nonce."])
  23. }
  24. let gcm = GCM(iv: nonce, mode: .combined)
  25. let aes = try AES(key: sharedKey, blockMode: gcm, padding: .noPadding)
  26. let encryptedBytes = try aes.encrypt(Array(dataToEncrypt))
  27. let finalData = Data(nonce + encryptedBytes)
  28. return finalData.base64EncodedString()
  29. }
  30. }