patbef-iOS/Befund/Core/Security/AES.swift

161 lines
5.1 KiB
Swift

//
// 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)!
}
}
}
}