Algorithm.swift 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // Algorithm.swift
  3. // Bark
  4. //
  5. // Created by huangfeng on 2023/2/23.
  6. // Copyright © 2023 Fin. All rights reserved.
  7. //
  8. import CryptoSwift
  9. import Foundation
  10. enum Algorithm: String {
  11. case aes128 = "AES128"
  12. case aes192 = "AES192"
  13. case aes256 = "AES256"
  14. var modes: [String] {
  15. switch self {
  16. case .aes128, .aes192, .aes256:
  17. return ["CBC", "ECB", "GCM"]
  18. }
  19. }
  20. var paddings: [String] {
  21. switch self {
  22. case .aes128, .aes192, .aes256:
  23. return ["pkcs7"]
  24. }
  25. }
  26. var keyLength: Int {
  27. switch self {
  28. case .aes128:
  29. return 16
  30. case .aes192:
  31. return 24
  32. case .aes256:
  33. return 32
  34. }
  35. }
  36. }
  37. struct CryptoSettingFields: Codable {
  38. let algorithm: String
  39. let mode: String
  40. let padding: String
  41. let key: String?
  42. var iv: String?
  43. }
  44. struct AESCryptoModel {
  45. let key: String
  46. let mode: BlockMode
  47. let padding: Padding
  48. let aes: AES
  49. init(cryptoFields: CryptoSettingFields) throws {
  50. guard let algorithm = Algorithm(rawValue: cryptoFields.algorithm) else {
  51. throw "Invalid algorithm"
  52. }
  53. guard let key = cryptoFields.key else {
  54. throw "Key is missing"
  55. }
  56. guard algorithm.keyLength == key.count else {
  57. throw String(format: NSLocalizedString("enterKey"), algorithm.keyLength)
  58. }
  59. var iv = ""
  60. if ["CBC", "GCM"].contains(cryptoFields.mode) {
  61. let expectIVLength = [
  62. "CBC": 16,
  63. "GCM": 12
  64. ][cryptoFields.mode] ?? 0
  65. if let ivField = cryptoFields.iv, ivField.count == expectIVLength {
  66. iv = ivField
  67. }
  68. else {
  69. throw String(format: NSLocalizedString("enterIv"), expectIVLength)
  70. }
  71. }
  72. let mode: BlockMode
  73. switch cryptoFields.mode {
  74. case "CBC":
  75. mode = CBC(iv: iv.bytes)
  76. case "ECB":
  77. mode = ECB()
  78. case "GCM":
  79. mode = GCM(iv: iv.bytes)
  80. default:
  81. throw "Invalid Mode"
  82. }
  83. self.key = key
  84. self.mode = mode
  85. self.padding = Padding.pkcs7
  86. self.aes = try AES(key: key.bytes, blockMode: self.mode, padding: self.padding)
  87. }
  88. func encrypt(text: String) throws -> String {
  89. return try aes.encrypt(Array(text.utf8)).toBase64()
  90. }
  91. func decrypt(ciphertext: String) throws -> String {
  92. return String(data: Data(try aes.decrypt(Array(base64: ciphertext))), encoding: .utf8) ?? ""
  93. }
  94. }