161 lines
5.1 KiB
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)!
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|