I am trying to communicate with a Java server over TCP, but I'm having issues trying to make the data secure in transit using RSA and AES. The server creates an AES key, encodes it in utf8, and sends it to the IOS Client, where it should be decoded back into a byte array as a Data object. Then, Using the Cryptokit framework, I try to create a SecKey object from it. I am stumped when trying to do so, though:
func createSecKeyFromAESKeyData(aesKeyData: Data) -> SecKey? {
// Define the key attributes
let keyAttributes: [CFString: Any] = [
kSecAttrKeyClass: kSecAttrKeyClassSymmetric,
kSecAttrKeySizeInBits: 128,
kSecAttrIsPermanent: false
]
// Convert the AES key data into a SecKey object
var error: Unmanaged<CFError>?
guard let key = SecKeyCreateWithData(aesKeyData as CFData, keyAttributes as CFDictionary, &error) else {
if let error = error {
print("Error creating SecKey: \(error.takeRetainedValue() as Error)")
} else {
print("Unknown error creating SecKey")
}
return nil
}
return key
}
Despite setting up my key attribute dictionary with the correct information (AES_128_GCM_SHA256, 128 bits, impermanent) based on how I generate it in the Java code, I keep getting a runtime error at the SecKeyCreateWithData call stating "Unsupported symmetric key type: 4865". I am unsure what this means and how to fix it as there doesn't seem to be any information on it online. If it helps, the Java code is using AES GCM with no padding, and we have confirmed that the data being sent is indeed 128 bits. How can I take this byte array and create a SecKey from it properly so we can pass secure data?
Similarly, I have also tried using RSA encryption for some data, but with this method, I generate the key pair on the iOS client and send the parts of the public key to the Java server where it (seemingly correctly) created the cipher from the passed data. However, trying to send anything encrypted back resulted in "RSAdecrypt wrong input (err -27)" when decrypting:
func decryptAESKey(encryptedKeyData: Data, privateKey: SecKey) -> Data? {
// Decrypt the received AES key using the private key
var error: Unmanaged<CFError>?
guard let decryptedKeyData = SecKeyCreateDecryptedData(privateKey, .rsaEncryptionOAEPSHA256, encryptedKeyData as CFData, &error) as Data? else {
print("Error decrypting AES key:", error!.takeRetainedValue() as Error)
return nil
}
return decryptedKeyData
}
Any assistance in figuring out how to properly use SecKeys in these ways would be greatly appreciated. Additionally, the relevant Java code can be provided if necessary.