Monday, February 10, 2020

XOR encryption and decryption with Swift

In most iOS apps we might have API key constants. Instead of keeping them as plain text, we can use XOR encrypted value and decrypt on app launch.
/// XOR encrypt plain text with a key.
/// - Parameters:
/// - plainText: A plain text for encryption.
/// - withKey: Encryption key.
/// - Returns: An array containing encrypted bytes
func xorEncrypt(_ plainText: String, withKey: String) -> [UInt8] {
var encrypted: [UInt8] = []
if plainText.isEmpty {
return []
}
let text: [UInt8] = Array(plainText.utf8)
let key: [UInt8] = Array(withKey.utf8)
let len = key.count
text.enumerated().forEach { idx, elem in
encrypted.append(elem ^ key[idx % len])
}
return encrypted
}

/// XOR decrypt cipher text with a key.
/// - Parameters:
/// - cipherText: A cipher text for decryption.
/// - withKey: Decryption key.
/// - Returns: The decrypted string.
func xorDecrypt(_ cipherText: [UInt8], withKey: String) -> String {
var decrypted: [UInt8] = []
if cipherText.count == 0 {
return ""
}
let key: [UInt8] = Array(withKey.utf8)
let len = key.count
cipherText.enumerated().forEach { idx, elem in
decrypted.append(elem ^ key[idx % len])
}
return String(bytes: decrypted, encoding: .utf8)!
}
Using the above xorEncrypt function will give an array of numbers which we can add as a constant. On app launch, use the xorDecrypt function with the array value and the same key to get the plain text back.