Skip to content

Instantly share code, notes, and snippets.

@levantAJ
Last active June 22, 2022 19:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save levantAJ/99f7053e8f7bf92738c98088aff035e3 to your computer and use it in GitHub Desktop.
Save levantAJ/99f7053e8f7bf92738c98088aff035e3 to your computer and use it in GitHub Desktop.
Encrypt a String with AES256/ECB/PKCS5 with a password
// MARK: - String
extension String {
func aes256ECBPKCS5(hexKey: String) throws -> Data {
let keyData: NSData = try Data(hex: hexKey) as NSData
let data: NSData = Data(utf8) as NSData
guard let cryptData: NSMutableData = NSMutableData(length: Int(data.length) + kCCBlockSizeAES128) else {
throw NSError(domain: "", code: 1234, userInfo: [NSLocalizedDescriptionKey: "Prepare crypt data failed"])
}
let keyLength: size_t = size_t(kCCKeySizeAES256)
let operation: CCOperation = UInt32(kCCEncrypt)
let algorithm: CCAlgorithm = UInt32(kCCAlgorithmAES)
let options: CCOptions = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding) // kCCOptionPKCS7Padding used as PKCS5Padding
var numBytesEncrypted: size_t = 0
let cryptStatus: CCCryptorStatus = CCCrypt(
operation,
algorithm,
options,
keyData.bytes,
keyLength,
nil,
data.bytes,
data.length,
cryptData.mutableBytes,
cryptData.length,
&numBytesEncrypted
)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
var bytes: [UInt8] = Array(repeating: 0, count: cryptData.length)
cryptData.getBytes(&bytes, length: cryptData.length)
return Data(bytes)
}
throw NSError(domain: "", code: 1234, userInfo: [NSLocalizedDescriptionKey: "Key is not HEX String format"])
}
}
// MARK: - Data
private extension Data {
init(hex: String) throws {
guard hex.count.isMultiple(of: 2) else {
throw NSError(domain: "", code: 1234, userInfo: [NSLocalizedDescriptionKey: "Key is not HEX String format"])
}
let chars: [Character] = hex.map { $0 }
let charCounts: StrideTo<Int> = stride(from: 0, to: chars.count, by: 2)
let hexStrings: [String] = charCounts.map { String(chars[$0]) + String(chars[$0 + 1]) }
let bytes: [UInt8] = hexStrings.compactMap { UInt8($0, radix: 16) }
guard hex.count / bytes.count == 2 else {
throw NSError(domain: "", code: 1234, userInfo: [NSLocalizedDescriptionKey: "Key is corrupted"])
}
self.init(bytes)
}
}
@levantAJ
Copy link
Author

How to use:

do {
    let encryptedData: Data = try "Hello World".aes256ECBPKCS5(hexKey: "b109dba59329b93f3fab0736d2d27e6b6a536482ef8c7fe061d7eeca68cefee6")
    print("Encrypted data: ", \(encryptedData))
} catch {
    print("Encrypted error: ", \(error))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment