Swift 5 - Расшифровка массива с помощью CommonCrypto - PullRequest
0 голосов
/ 13 июня 2019

Я работаю над шифрованием конфиденциальных данных пользователя в типе Array с помощью Common Crypto. Я имею в виду пример кода CommonCrypto по ссылке ниже:

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

Проблема, по-видимому, при декодировании возвращается ноль. Последовательность, которую я пытаюсь сделать, следующая:

  1. Кодирование данных пользователя в массиве в данные с помощью JSONEncoder
  2. Шифрование данных, полученных с # 1, с помощью Common Crypto
  3. Сохраните зашифрованные данные, полученные из # 2, в связку ключей.
  4. Получить данные из цепочки для ключей.
  5. Расшифровать полученные данные из # 4 с помощью Common Crypto
  6. Расшифруйте расшифрованные данные из # 5 с помощью JSONDecoder, и я думаю, что это проблема. При декодировании консоль печатает байты, поэтому предположим, что она успешно расшифрована, но при декодировании возвращается сообщение об ошибке с сообщением об ошибке ниже:

"dataCorrupted (Swift.DecodingError.Context (codingPath: [], debugDescription:« Указанные данные не были действительными в формате JSON. », UnderError: Необязательный (Ошибка домена = NSCocoaErrorDomain Code = 3840) Текст JSON не начинался с массива или объект и параметр, позволяющие не задавать фрагменты. "UserInfo = {NSDebugDescription = Текст JSON не начинался с массива или объекта, а также параметр, позволяющий не задавать фрагменты.})))"

Если я кодирую массив с помощью PropertyListEncoder, при декодировании возвращается аналогичное сообщение.

dataCorrupted (Swift.DecodingError.Context (codingPath: [], debugDescription: «Указанные данные не были допустимым списком свойств.», UnderError: Необязательный (Ошибка домена = NSCocoaErrorDomain Code = 3840 «Неожиданный символ Ï в строке 1») UserInfo = {NSDebugDescription = Неожиданный символ Ï в строке 1, kCFPropertyListOldStyleParsingError = Ошибка домена = NSCocoaErrorDomain Code = 3840 "Ошибка преобразования строки." UserInfo = {NSDebugDescription = Преобразование строки не удалось.}})))

Я обнаружил, что большинство кодов, которые я видел, это кодирование строки в данные с использованием кодировщика строки, поэтому я попытался использовать JSONEncoder / Decoder для работы с массивом.

Ниже мой код:

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
}

}

Мне нужно, чтобы шифрование работало нормально, поскольку это важные данные пользователя, и я считаю это своим главным приоритетом. Теперь я думаю, может быть, я делаю это очень неправильно, поскольку я новичок в программировании, поэтому я был бы очень признателен, если бы кто-нибудь дал проницательный совет. Пожалуйста, помогите!

...