Add AESCryptoModel

This commit is contained in:
Fin 2023-03-03 16:04:26 +08:00
parent 6d4acccf28
commit 9e1ee4bebd
No known key found for this signature in database
GPG Key ID: CFB59B99D87A7B93
11 changed files with 272 additions and 94 deletions

View File

@ -126,7 +126,14 @@
06CF784C21C7A51200A052D7 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06CF784B21C7A51200A052D7 /* NotificationService.swift */; };
06EE1FD326843E9300586708 /* BarkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06EE1FD226843E9300586708 /* BarkTests.swift */; };
06EEF333291CCFF400CA228A /* CryptoSettingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06EEF332291CCFF400CA228A /* CryptoSettingController.swift */; };
06EEF335291CD00000CA228A /* CryptoSettingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06EEF334291CD00000CA228A /* CryptoSettingModel.swift */; };
06EEF335291CD00000CA228A /* CryptoSettingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06EEF334291CD00000CA228A /* CryptoSettingViewModel.swift */; };
06F08EA429B098DD006AB9CA /* CryptoSettingManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F08EA329B098DD006AB9CA /* CryptoSettingManager.swift */; };
06F08EA529B1DDA7006AB9CA /* Algorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 061894C629A75BEA00E001C2 /* Algorithm.swift */; };
06F08EA729B1DDFE006AB9CA /* Error+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F08EA629B1DDFE006AB9CA /* Error+Extension.swift */; };
06F08EA829B1DE0A006AB9CA /* Error+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F08EA629B1DDFE006AB9CA /* Error+Extension.swift */; };
06F08EAA29B1DE9F006AB9CA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 063C499720E36BF9001BCA35 /* Localizable.strings */; };
06F08EAC29B1DECD006AB9CA /* NSLocalizedString+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F08EAB29B1DECD006AB9CA /* NSLocalizedString+Extension.swift */; };
06F08EAD29B1DED6006AB9CA /* NSLocalizedString+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F08EAB29B1DECD006AB9CA /* NSLocalizedString+Extension.swift */; };
06F11E7727D9D5FB00F00298 /* QRScannerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F11E7627D9D5FB00F00298 /* QRScannerViewController.swift */; };
3428272069AFAFE2C683FEB0 /* libPods-Bark.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CCC722470308049D180876C7 /* libPods-Bark.a */; };
879AE4D4178855A9672009E4 /* libPods-NotificationServiceExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B7F8BDFAA047451561798F58 /* libPods-NotificationServiceExtension.a */; };
@ -306,7 +313,10 @@
06EE1FD226843E9300586708 /* BarkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarkTests.swift; sourceTree = "<group>"; };
06EE1FD426843E9300586708 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
06EEF332291CCFF400CA228A /* CryptoSettingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoSettingController.swift; sourceTree = "<group>"; };
06EEF334291CD00000CA228A /* CryptoSettingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoSettingModel.swift; sourceTree = "<group>"; };
06EEF334291CD00000CA228A /* CryptoSettingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoSettingViewModel.swift; sourceTree = "<group>"; };
06F08EA329B098DD006AB9CA /* CryptoSettingManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoSettingManager.swift; sourceTree = "<group>"; };
06F08EA629B1DDFE006AB9CA /* Error+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+Extension.swift"; sourceTree = "<group>"; };
06F08EAB29B1DECD006AB9CA /* NSLocalizedString+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSLocalizedString+Extension.swift"; sourceTree = "<group>"; };
06F11E7627D9D5FB00F00298 /* QRScannerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRScannerViewController.swift; sourceTree = "<group>"; };
121D9B1ED4E8D26F345BC5C0 /* Pods-BarkTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BarkTests.release.xcconfig"; path = "Target Support Files/Pods-BarkTests/Pods-BarkTests.release.xcconfig"; sourceTree = "<group>"; };
138CE8CB688587E893BC5C44 /* Pods-Bark.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Bark.debug.xcconfig"; path = "Target Support Files/Pods-Bark/Pods-Bark.debug.xcconfig"; sourceTree = "<group>"; };
@ -387,7 +397,7 @@
068EC15727ED99C900D5D11E /* ServerListViewController.swift */,
068EC15927ED99E700D5D11E /* ServerListViewModel.swift */,
06EEF332291CCFF400CA228A /* CryptoSettingController.swift */,
06EEF334291CD00000CA228A /* CryptoSettingModel.swift */,
06EEF334291CD00000CA228A /* CryptoSettingViewModel.swift */,
);
path = Controller;
sourceTree = "<group>";
@ -504,6 +514,9 @@
0633E809256A091B00ED0680 /* MJRefresh+Rx.swift */,
06840DBA272298FB001B3193 /* BKColor.swift */,
065AE76A2987777F00323230 /* ArchiveSettingRelay.swift */,
06F08EA329B098DD006AB9CA /* CryptoSettingManager.swift */,
06F08EA629B1DDFE006AB9CA /* Error+Extension.swift */,
06F08EAB29B1DECD006AB9CA /* NSLocalizedString+Extension.swift */,
);
path = Common;
sourceTree = "<group>";
@ -841,6 +854,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
06F08EAA29B1DE9F006AB9CA /* Localizable.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -988,12 +1002,14 @@
06EEF333291CCFF400CA228A /* CryptoSettingController.swift in Sources */,
0603706D20E23EC000F4CA05 /* BarkSFSafariViewController.swift in Sources */,
06AE311A266F4E6600B39FBB /* GroupFilterViewModel.swift in Sources */,
06F08EA429B098DD006AB9CA /* CryptoSettingManager.swift in Sources */,
06BD4DAA2901352E003364DB /* Object+Dictionary.swift in Sources */,
06C5953124811392006B98F3 /* ArchiveSettingCell.swift in Sources */,
068EC15A27ED99E700D5D11E /* ServerListViewModel.swift in Sources */,
06172FDC27F6DB06002333A4 /* ServerListTableViewCellViewModel.swift in Sources */,
061894C729A75BEA00E001C2 /* Algorithm.swift in Sources */,
065BE4502563D939002A8CA4 /* SoundCellViewModel.swift in Sources */,
06F08EA729B1DDFE006AB9CA /* Error+Extension.swift in Sources */,
06B1158F247BB1FB006D91FB /* Message.swift in Sources */,
06172FDA27F6DAEF002333A4 /* ServerListTableViewCell.swift in Sources */,
061894C529962EB900E001C2 /* GradientButton.swift in Sources */,
@ -1029,7 +1045,7 @@
06C2CF252685BDB80034B127 /* SpacerCell.swift in Sources */,
06BBB8BC2567B3AD0076F63E /* ArchiveSettingCellViewModel.swift in Sources */,
0642B55A27EB13F100453D91 /* MutableTextCell.swift in Sources */,
06EEF335291CD00000CA228A /* CryptoSettingModel.swift in Sources */,
06EEF335291CD00000CA228A /* CryptoSettingViewModel.swift in Sources */,
0637FA8020E0981E00E80174 /* BarkSettings.swift in Sources */,
065BE4402563D649002A8CA4 /* SoundsViewModel.swift in Sources */,
065BE4462563D7E5002A8CA4 /* ViewModelType.swift in Sources */,
@ -1039,6 +1055,7 @@
06BBB8C12567B3EF0076F63E /* BaseTableViewCell.swift in Sources */,
0661A543204FDA4100965E4E /* AppDelegate.swift in Sources */,
065AE76B2987777F00323230 /* ArchiveSettingRelay.swift in Sources */,
06F08EAC29B1DECD006AB9CA /* NSLocalizedString+Extension.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1047,8 +1064,11 @@
buildActionMask = 2147483647;
files = (
06CF784C21C7A51200A052D7 /* NotificationService.swift in Sources */,
06F08EAD29B1DED6006AB9CA /* NSLocalizedString+Extension.swift in Sources */,
06F08EA529B1DDA7006AB9CA /* Algorithm.swift in Sources */,
06BBB89125650CCF0076F63E /* ArchiveSettingManager.swift in Sources */,
06B11591247BC132006D91FB /* Message.swift in Sources */,
06F08EA829B1DE0A006AB9CA /* Error+Extension.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -0,0 +1,41 @@
//
// CryptoSettingManager.swift
// Bark
//
// Created by huangfeng on 2023/3/2.
// Copyright © 2023 Fin. All rights reserved.
//
import Foundation
import RxCocoa
class CryptoSettingManager: NSObject {
static let shared = CryptoSettingManager()
let defaults = UserDefaults(suiteName: "group.bark")
var fields: CryptoSettingFields? {
get {
return defaults?.value(forKey: "cryptoSettingFields") as? CryptoSettingFields
}
set {
defaults?.set(newValue, forKey: "cryptoSettingFields")
}
}
override private init() {
super.init()
}
}
class CryptoSettingRelay: NSObject {
static let shared = CryptoSettingRelay()
let fields: BehaviorRelay<CryptoSettingFields?>
override private init() {
self.fields = BehaviorRelay<CryptoSettingFields?>(value: CryptoSettingManager.shared.fields)
super.init()
self.fields.subscribe { val in
CryptoSettingManager.shared.fields = val
}.disposed(by: rx.disposeBag)
}
}

View File

@ -28,10 +28,6 @@ extension UIViewController {
}
}
func NSLocalizedString(_ key: String) -> String {
return NSLocalizedString(key, comment: "")
}
let kNavigationHeight: CGFloat = {
kSafeAreaInsets.top + 44
}()

View File

@ -0,0 +1,11 @@
//
// Error+Extension.swift
// Bark
//
// Created by huangfeng on 2023/3/3.
// Copyright © 2023 Fin. All rights reserved.
//
import Foundation
extension String: Error {}

View File

@ -0,0 +1,13 @@
//
// NSLocalizedString+Extension.swift
// Bark
//
// Created by huangfeng on 2023/3/3.
// Copyright © 2023 Fin. All rights reserved.
//
import Foundation
func NSLocalizedString(_ key: String) -> String {
return NSLocalizedString(key, comment: "")
}

View File

@ -6,10 +6,10 @@
// Copyright © 2022 Fin. All rights reserved.
//
import UIKit
import RxSwift
import UIKit
class CryptoSettingController: BaseViewController<CryptoSettingModel> {
class CryptoSettingController: BaseViewController<CryptoSettingViewModel> {
let algorithmFeild = DropBoxView(values: ["AES128", "AES192", "AES256"])
let modeFeild = DropBoxView(values: ["CBC", "ECB", "GCM"])
let paddingField = DropBoxView(values: ["pkcs7"])
@ -26,14 +26,6 @@ class CryptoSettingController: BaseViewController<CryptoSettingModel> {
textField.font = UIFont.systemFont(ofSize: 14)
textField.placeholder = NSLocalizedString("enterIv")
return textField
}()
let previewLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 12)
label.textColor = BKColor.grey.darken4
label.text = "\(NSLocalizedString("preview")): \"helloworld\" -> \"DASGKJLSAJKGH==\""
return label
}()
let doneButton: BKButton = {
@ -57,7 +49,8 @@ class CryptoSettingController: BaseViewController<CryptoSettingModel> {
UIColor(r255: 36, g255: 51, b255: 236),
UIColor(r255: 70, g255: 44, b255: 233),
],
gradientOrientation: .horizontal)
gradientOrientation: .horizontal
)
return btn
}()
@ -104,7 +97,6 @@ class CryptoSettingController: BaseViewController<CryptoSettingModel> {
self.scrollView.addSubview(ivLabel)
self.scrollView.addSubview(ivTextField)
self.scrollView.addSubview(previewLabel)
self.scrollView.addSubview(copyButton)
self.view.backgroundColor = UIColor.white
@ -157,16 +149,12 @@ class CryptoSettingController: BaseViewController<CryptoSettingModel> {
make.top.equalTo(ivLabel.snp.bottom).offset(5)
}
previewLabel.snp.makeConstraints { make in
make.left.equalTo(ivLabel)
make.top.equalTo(ivTextField.snp.bottom).offset(20)
}
copyButton.snp.makeConstraints { make in
make.left.equalTo(ivTextField)
make.right.equalTo(ivTextField)
make.height.equalTo(42)
make.top.equalTo(previewLabel.snp.bottom).offset(10)
make.top.equalTo(ivTextField.snp.bottom).offset(25)
make.bottom.equalToSuperview().offset(-20)
}
@ -184,11 +172,33 @@ class CryptoSettingController: BaseViewController<CryptoSettingModel> {
override func bindViewModel() {
let output = viewModel.transform(input: CryptoSettingModel.Input(
func getFieldValues() -> CryptoSettingFields {
return CryptoSettingFields(
algorithm: self.algorithmFeild.currentValue!,
mode: self.modeFeild.currentValue!,
padding: self.paddingField.currentValue!,
key: self.keyTextField.text,
iv: self.ivTextField.text
)
}
let output = viewModel.transform(input: CryptoSettingViewModel.Input(
algorithmChanged: self.algorithmFeild
.rx
.currentValueChanged
.compactMap { $0 }
.asDriver(onErrorDriveWith: .empty()),
copyScript: copyButton
.rx
.tap
.map { getFieldValues() }
.asDriver(onErrorDriveWith: .empty()),
done: doneButton
.rx
.tap
.map { getFieldValues() }
.asDriver(onErrorDriveWith: .empty())
))

View File

@ -1,56 +0,0 @@
//
// CryptoSettingModel.swift
// Bark
//
// Created by huangfeng on 2022/11/10.
// Copyright © 2022 Fin. All rights reserved.
//
import CryptoSwift
import Foundation
import RxCocoa
import RxSwift
class CryptoSettingModel: ViewModel, ViewModelType {
struct Input {
let algorithmChanged: Driver<String>
}
struct Output {
let algorithmList: Driver<[Algorithm]>
let modeList: Driver<[String]>
let paddingList: Driver<[String]>
let keyLenght: Driver<Int>
}
func transform(input: Input) -> Output {
let modeList = input
.algorithmChanged
.compactMap { Algorithm(rawValue: $0) }
.map { $0.modes }
let keyLenght = input
.algorithmChanged
.compactMap { Algorithm(rawValue: $0) }
.map { $0.keyLenght }
return Output(
algorithmList: Driver.just([Algorithm.aes128, Algorithm.aes192, Algorithm.aes256]),
modeList: Driver.merge(Driver.just(["CBC", "ECB", "GCM"]), modeList),
paddingList: Driver.just(["pkcs7"]),
keyLenght: Driver.merge(Driver.just(16), keyLenght)
)
}
override init() {
super.init()
do {
let aes = try AES(key: "ABCDEFGHIJKLMNOP", iv: "1234567890123456") // aes128
let ciphertext = try aes.encrypt(Array("hello,world".utf8))
print("tttt \(ciphertext.toBase64())")
} catch {
print("tttt \(error.rawString())")
}
}
}

View File

@ -0,0 +1,82 @@
//
// CryptoSettingViewModel.swift
// Bark
//
// Created by huangfeng on 2022/11/10.
// Copyright © 2022 Fin. All rights reserved.
//
import CryptoSwift
import Foundation
import RxCocoa
import RxSwift
class CryptoSettingViewModel: ViewModel, ViewModelType {
struct Input {
let algorithmChanged: Driver<String>
let copyScript: Driver<CryptoSettingFields>
let done: Driver<CryptoSettingFields>
}
struct Output {
let algorithmList: Driver<[Algorithm]>
let modeList: Driver<[String]>
let paddingList: Driver<[String]>
let keyLenght: Driver<Int>
var showSnackbar: Driver<String>
}
struct Dependencies {
let settingFieldRelay: BehaviorRelay<CryptoSettingFields?>
}
private let dependencies: Dependencies
init(dependencies: Dependencies =
Dependencies(
settingFieldRelay: CryptoSettingRelay.shared.fields
)
) {
self.dependencies = dependencies
}
func transform(input: Input) -> Output {
let showSnackbar = PublishRelay<String>()
let modeList = input
.algorithmChanged
.compactMap { Algorithm(rawValue: $0) }
.map { $0.modes }
let keyLenght = input
.algorithmChanged
.compactMap { Algorithm(rawValue: $0) }
.map { $0.keyLenght }
//
input.done
.filter { fields in
do {
_ = try AESCryptoModel(cryptoFields: fields)
return true
}
catch {
showSnackbar.accept(error.rawString())
return false
}
}.drive(onNext: { [weak self] fields in
//
self?.dependencies.settingFieldRelay.accept(fields)
}).disposed(by: rx.disposeBag)
return Output(
algorithmList: Driver.just([Algorithm.aes128, Algorithm.aes192, Algorithm.aes256]),
modeList: Driver.merge(Driver.just(["CBC", "ECB", "GCM"]), modeList),
paddingList: Driver.just(["pkcs7"]),
keyLenght: Driver.merge(Driver.just(16), keyLenght),
showSnackbar: showSnackbar.asDriver(onErrorDriveWith: .empty())
)
}
}

View File

@ -6,6 +6,7 @@
// Copyright © 2023 Fin. All rights reserved.
//
import CryptoSwift
import Foundation
enum Algorithm: String {
@ -38,3 +39,62 @@ enum Algorithm: String {
}
}
}
struct CryptoSettingFields {
let algorithm: String
let mode: String
let padding: String
let key: String?
let 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.keyLenght == key.count else {
throw String(format: NSLocalizedString("enterKey"), algorithm.keyLenght)
}
var iv = ""
if ["CBC", "GCM"].contains(cryptoFields.mode) {
if let ivField = cryptoFields.iv, ivField.count == 16 {
iv = ivField
}
}
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) ?? ""
}
}

View File

@ -43,6 +43,7 @@ end
target 'NotificationServiceExtension' do
pod 'IceCream'
pod 'Kingfisher'
pod 'CryptoSwift'
end
post_install do |installer|

View File

@ -147,6 +147,6 @@ SPEC CHECKSUMS:
SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6
SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e
PODFILE CHECKSUM: a6d53e3d3f1c8c892f61c29cc990d7b70691d966
PODFILE CHECKSUM: caaf0ea0ab301807957ab7217eb404aff861f92c
COCOAPODS: 1.11.3