// // AES.swift // Befund // // Created by Irakli Abetschkhrischwili on 29.04.22. // Copyright © 2022 MVZ Dr. Stein und Kollegen. All rights reserved. import Foundation import CryptoKit extension Core.Security { public class AES { public static let PGS_ENCRYPT_PARTIAL_KEY = "wA6j@x.CcmM>~5Ss^C_!#,zch)$YsDsd59,::>dW#F`@U]Ye5ETZcMT7}&+#*!%z" /** * Encrypts string with password (string) * * @param value - string value that should be encrypted * @param password - string password that should be used for encryption(max. 32 bytes) * @return - returns encrypted base64 string */ static func Encrypt(value: String, password: String) -> String? { var result: String? = nil do { let key = SymmetricKey(data: GetKey(password: password)) let data = value.data(using: .utf8) if(data != nil) { let encrypted = try CryptoKit.AES.GCM.seal(data!, using: key) result = encrypted.combined!.base64EncodedString() } } catch { Core.Log.Error(err: error, namespace: "Core.Security.AES", method: "Encrypt(string, string)") } return result } /** * Encrypts string with key * * @param value - string value that should be encrypted * @param deriveKey - shared deriveKey that should be used for encryption(max. 32 bytes) * @return - returns encrypted base64 string */ static func Encrypt(value: String, deriveKey: CryptoKit.SymmetricKey) -> String? { var result: String? = nil do { let data = value.data(using: .utf8) if(data != nil) { let encrypted = try CryptoKit.AES.GCM.seal(data!, using: deriveKey) result = Base64.ToBase64String(data: encrypted.combined!) } } catch { Core.Log.Error(err: error, namespace: "Core.Security.AES", method: "Encrypt(String, SymmetricKey)") } return result } /** * Decrypts encrypted base64 string with key * * @param value - base64 string that should be decrypted * @param deriveKey - key that should be used for the decryption(max. 32 bytes) * @return */ static func Decrypt(value: String, deriveKey: CryptoKit.SymmetricKey) -> String? { var result: String? = nil do { let data = Data(base64Encoded: value) if(data != nil) { let sealedData = try CryptoKit.AES.GCM.SealedBox(combined: data!) let decryptedData = try CryptoKit.AES.GCM.open(sealedData, using: deriveKey) result = String(data: decryptedData, encoding: .utf8) } } catch { result = nil } return result } /** * Decrypts encrypted base64 string with password(string) * * @param value - base64 string that should be decrypted * @param password - string password that should be used for the decryption(max. 32 bytes) * @return */ static func Decrypt(value: String, password: String) -> String? { var result: String? = nil do { let key = SymmetricKey(data: GetKey(password: password)) let data = Data(base64Encoded: value) if(data != nil) { let sealedData = try CryptoKit.AES.GCM.SealedBox(combined: data!) let decryptedData = try CryptoKit.AES.GCM.open(sealedData, using:key) result = String(data: decryptedData, encoding: .utf8) } } catch let error { Core.Log.Error(err: error, namespace: "AES", method: "Decrypt") result = nil } return result } /** * Converts the text passed password to the 32 byte array * * @param password - Text based password * @return returns password as byte array */ static func GetKey(password: String) -> Data { if(password.count < 32) { return password.padding(toLength: 32, withPad: "@", startingAt: 0).data(using: .ascii)! } else if(password.count > 32) { return MD5.Encrypt(value: password).data(using: .ascii)! } else { return password.data(using: .ascii)! } } } }