Created
June 26, 2023 08:26
-
-
Save elpsk/08c4f2c9c9369b50a5458acc720ea668 to your computer and use it in GitHub Desktop.
CryptoManager - encrypt / decrypt files for macOS using AES
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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