In most 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. Advantage being searching the binary for strings will not show the encryption keys.
/// 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.