Skip to content

Instantly share code, notes, and snippets.

@elpsk
Created June 26, 2023 08:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elpsk/08c4f2c9c9369b50a5458acc720ea668 to your computer and use it in GitHub Desktop.
Save elpsk/08c4f2c9c9369b50a5458acc720ea668 to your computer and use it in GitHub Desktop.
CryptoManager - encrypt / decrypt files for macOS using AES
import Cocoa
import CommonCrypto
class CryptoManager {
static var defaultCryptoKey: String? {
set {
if let key = newValue {
StorageManager.save(cryptoKey: key)
}
}
get {
return StorageManager.read()
}
}
func encryptFile(atPath filePath: String, withKey key: String, deleteSource: Bool) throws {
let fileURL = URL(fileURLWithPath: filePath)
let fileData = try Data(contentsOf: fileURL)
guard let encryptedData = encrypt(data: fileData, key: key) else {
throw NSError(domain: "EncryptionError", code: -1, userInfo: nil)
}
let encryptedFile = "\(filePath).psk"
try encryptedData.write(to: URL(filePath: encryptedFile), options: .atomic)
print("File encrypted successfully.")
if deleteSource {
deleteOriginalFile(atPath: filePath)
}
}
func decryptFile(atPath filePath: String, withKey key: String, deleteSource: Bool) throws {
let fileURL = URL(fileURLWithPath: filePath)
let fileData = try Data(contentsOf: fileURL)
guard let decryptedData = decrypt(data: fileData, key: key) else {
throw NSError(domain: "DecryptionError", code: -1, userInfo: nil)
}
let decryptedFile = filePath.replacingOccurrences(of: ".psk", with: "")
try decryptedData.write(to: URL(filePath: decryptedFile), options: .atomic)
print("File decrypted successfully.")
if deleteSource {
deleteOriginalFile(atPath: filePath)
}
}
private func deleteOriginalFile( atPath filePath: String ) {
do {
try FileManager.default.removeItem(atPath: filePath)
} catch {
print( error )
}
}
// ---
private func encrypt(data: Data, key: String) -> Data? {
let keyData = key.data(using: .utf8)!
let inputData = data as NSData
let encryptedData = NSMutableData(length: Int(inputData.length) + kCCBlockSizeAES128)!
let keyLength = size_t(kCCKeySizeAES128)
let operation = CCOperation(kCCEncrypt)
let algorithm = CCAlgorithm(kCCAlgorithmAES)
let options = CCOptions(kCCOptionPKCS7Padding)
var numBytesEncrypted: size_t = 0
let cryptStatus = CCCrypt(
operation,
algorithm,
options,
(keyData as NSData).bytes, keyLength,
nil,
inputData.bytes, inputData.length,
encryptedData.mutableBytes, encryptedData.length,
&numBytesEncrypted
)
if cryptStatus == kCCSuccess {
encryptedData.length = Int(numBytesEncrypted)
return encryptedData as Data
}
return nil
}
private func decrypt(data: Data, key: String) -> Data? {
let keyData = key.data(using: .utf8)!
let inputData = data as NSData
let decryptedData = NSMutableData(length: Int(inputData.length) + kCCBlockSizeAES128)!
let keyLength = size_t(kCCKeySizeAES128)
let operation = CCOperation(kCCDecrypt)
let algorithm = CCAlgorithm(kCCAlgorithmAES)
let options = CCOptions(kCCOptionPKCS7Padding)
var numBytesDecrypted: size_t = 0
let cryptStatus = CCCrypt(
operation,
algorithm,
options,
(keyData as NSData).bytes, keyLength,
nil,
inputData.bytes, inputData.length,
decryptedData.mutableBytes, decryptedData.length,
&numBytesDecrypted
)
if cryptStatus == kCCSuccess {
decryptedData.length = Int(numBytesDecrypted)
return decryptedData as Data
}
return nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment