Swift 5-使用CommonCrypto

时间:2019-06-13 00:02:43

标签: arrays encryption commoncrypto swift5

我正在使用Common Crypto对Array类型的用户敏感数据进行加密。我指的是下面链接中的CommonCrypto示例代码:

https://gist.github.com/hfossli/7165dc023a10046e2322b0ce74c596f8

问题,显然我在解码时返回了nil。我正在尝试的顺序如下:

  1. 使用JSONEncoder将数组中的用户数据编码为数据
  2. 使用通用加密技术加密从#1获得的数据
  3. 将从#2获得的加密数据存储到钥匙串中。
  4. 从钥匙串中检索数据。
  5. 使用通用加密解密从#4检索的数据
  6. 使用JSONDecoder对#5中的解密数据进行解码,这就是我认为麻烦的出处。解码控制台打印字节时,因此假设已成功解密,但是解码时返回以下错误消息,则返回nil:
  

“ dataCorrupted(Swift.DecodingError.Context(codingPath:[],debugDescription:“给定的数据不是有效的JSON。”,底层错误:可选(错误域= NSCocoaErrorDomain代码= 3840,” JSON文本不是以数组或对象和允许未设置片段的选项。“ UserInfo = {NSDebugDescription = JSON文本不是以数组或对象开头,并且没有允许设置片段的选项。})))”

如果我使用PropertyListEncoder对数组进行编码,则在解码时会返回类似的消息。

  

dataCorrupted(Swift.DecodingError.Context(codingPath:[],debugDescription:“给定的数据不是有效的属性列表。”,underlyingError:可选(错误域= NSCocoaErrorDomain代码= 3840“第1行出现意外字符“”) UserInfo = {NSDebugDescription =在第1行出现意外字符k,kCFPropertyListOldStyleParsingError =错误域= NSCocoaErrorDomain代码= 3840“字符串转换失败。” UserInfo = {NSDebugDescription =字符串转换失败。}}))))

我发现我看到的最多代码是使用String编码器将String编码为Data,这就是为什么我尝试使用JSONEncoder / Decoder与Array一起使用的原因。

下面是我的代码:

import Foundation
import KeychainAccess

class UserInformation: Codable, Equatable {

static func == (lhs: UserInformation, rhs: UserInformation) -> Bool {
    return lhs.isExpanded == rhs.isExpanded && lhs.isPinned == rhs.isPinned && lhs.sectionName == rhs.sectionName && lhs.userInformation == rhs.userInformation
}

var isExpanded: Bool
var isPinned: Bool
var sectionName: String
var userInformation: [String?]
var indexPathSection: Int?

init(isExpanded: Bool, isPinned: Bool, sectionName: String, userInformation: [String?], indexPathSection: Int?) {
    self.isExpanded = isExpanded
    self.isPinned = isPinned
    self.sectionName = sectionName
    self.userInformation = userInformation
    self.indexPathSection = indexPathSection
}

}

extension UserInformation {

static let jsonEncoder = JSONEncoder()
static let jsonDecoder = JSONDecoder()
static let keychain = Keychain(service: "com.KeeperApp-UserInfo")

static let password = ["Test"]
static let salt = AES256.randomSalt()
static let iv = AES256.randomIv()
static let key = try! AES256.createKey(password: passwordEncoder(), salt: salt)
static let aes = try! AES256(key: key, iv: iv)

static func passwordEncoder() -> Data {

    let jsonEncoder = JSONEncoder()
    let jsonData = try? jsonEncoder.encode(password)
    let data = try? jsonEncoder.encode(password)
    return data!
}

static func encrypting(data: Data?) -> Data? {
    do {
        let encrypted = try aes.encrypt(data!)
        return encrypted
    } catch {
        print("not Encrypted")
        return nil
    }
}

static func decrypting(encrypted: Data) -> Data {
    let decrypted = try! aes.decrypt(encrypted)
    return decrypted
}

static func saveToKeychain(userInfo: [UserInformation]) {
    if userInfo.isEmpty != true {
        let data = try? jsonEncoder.encode(userInfo)
        if let savingData = encrypting(data: data) {//data {
            keychain[data: "encodedUserInfo"] = NSData(data: savingData) as Data
        }
    } else {
        do {
            try keychain.remove("encodedUserInfo")
        } catch {
        }
    }
}

static func loadFromKeychain() -> [UserInformation]? {
    guard let retrievedEncryptedData = keychain[data: "encodedUserInfo"] else { return nil }
    print(retrievedEncryptedData)

    let decryptedData = decrypting(encrypted: retrievedEncryptedData)
    print(decryptedData)

    let loadedData: [UserInformation]?

    do {
        let data = try jsonDecoder.decode(Array<UserInformation>.self, from: decrypting(encrypted: retrievedEncryptedData))
        loadedData = data
        print(data)
    }
    catch {
        print(error)
        loadedData = nil
    }

    return loadedData
}

}

我必须使加密工作正常,因为它是用户的重要数据,并将其视为我的首要任务。现在,我正在想也许我做错了,因为我是编程新手,所以如果有人提供有见地的建议,将不胜感激。请帮忙!

0 个答案:

没有答案