Bark/Model/Algorithm.swift
2023-12-20 20:37:58 +08:00

112 lines
2.7 KiB
Swift

//
// Algorithm.swift
// Bark
//
// Created by huangfeng on 2023/2/23.
// Copyright © 2023 Fin. All rights reserved.
//
import CryptoSwift
import Foundation
enum Algorithm: String {
case aes128 = "AES128"
case aes192 = "AES192"
case aes256 = "AES256"
var modes: [String] {
switch self {
case .aes128, .aes192, .aes256:
return ["CBC", "ECB", "GCM"]
}
}
var paddings: [String] {
switch self {
case .aes128, .aes192, .aes256:
return ["pkcs7"]
}
}
var keyLength: Int {
switch self {
case .aes128:
return 16
case .aes192:
return 24
case .aes256:
return 32
}
}
}
struct CryptoSettingFields: Codable {
let algorithm: String
let mode: String
let padding: String
let key: String?
var iv: String?
}
struct AESCryptoModel {
let key: String
let mode: BlockMode
let padding: Padding
let aes: AES
init(cryptoFields: CryptoSettingFields) throws {
guard let algorithm = Algorithm(rawValue: cryptoFields.algorithm) else {
throw "Invalid algorithm"
}
guard let key = cryptoFields.key else {
throw "Key is missing"
}
guard algorithm.keyLength == key.count else {
throw String(format: NSLocalizedString("enterKey"), algorithm.keyLength)
}
var iv = ""
if ["CBC", "GCM"].contains(cryptoFields.mode) {
var expectIVLength = 0
if cryptoFields.mode == "CBC" {
expectIVLength = 16
}
else if cryptoFields.mode == "GCM" {
expectIVLength = 12
}
if let ivField = cryptoFields.iv, ivField.count == expectIVLength {
iv = ivField
}
else {
throw String(format: NSLocalizedString("enterIv"), expectIVLength)
}
}
let mode: BlockMode
switch cryptoFields.mode {
case "CBC":
mode = CBC(iv: iv.bytes)
case "ECB":
mode = ECB()
case "GCM":
mode = GCM(iv: iv.bytes)
default:
throw "Invalid Mode"
}
self.key = key
self.mode = mode
self.padding = Padding.pkcs7
self.aes = try AES(key: key.bytes, blockMode: self.mode, padding: self.padding)
}
func encrypt(text: String) throws -> String {
return try aes.encrypt(Array(text.utf8)).toBase64()
}
func decrypt(ciphertext: String) throws -> String {
return String(data: Data(try aes.decrypt(Array(base64: ciphertext))), encoding: .utf8) ?? ""
}
}