HI all,
I am trying to implement diffie-hellman key exchnage, by generating a secret key with an EC public key receives from API and the private key already generated in the project. Also I need to perform the KDF operation by passing some parameters. Here what my project code look like
generating the secret key
func generateSharedSecret(issuerPublicKey: SecKey, devicePrivateKey: SecKey, parameters:[SecKeyKeyExchangeParameter: Any] = [:]) throws -> Data? {
var error: Unmanaged<CFError>?
guard let shared = SecKeyCopyKeyExchangeResult(devicePrivateKey, .ecdhKeyExchangeStandard, issuerPublicKey, parameters as CFDictionary, &error) else {
let errStr = error?.takeRetainedValue().localizedDescription ?? "Derive Key Fail"
print(errStr)
throw error!.takeRetainedValue() as Error
}
return shared as Data
}
Setup parameters for performing secret key operation and KDF
var algId: Data, keyDataLen: Int
algId = "".data(using: .utf8)!
keyDataLen = 256
let algorithmID = prefixedBigEndenLen(from: algId)
let partyUInfo = prefixedBigEndenLen(from: apu)
let partyVInfo = prefixedBigEndenLen(from: apv)
let suppPubInfo = intToData(value: UInt32(keyDataLen).bigEndian)
let suppPrivInfo = Data()
let concatedData = algorithmID + partyUInfo + partyVInfo + suppPubInfo + suppPrivInfo
let params = [SecKeyKeyExchangeParameter.requestedSize: 32, SecKeyKeyExchangeParameter.sharedInfo: concatedData] as [SecKeyKeyExchangeParameter : Any]
// Function call:
let sharedSecret = try generateSharedSecret(issuerPublicKey: pubKey, devicePrivateKey: eprivKey, parameters: params as [SecKeyKeyExchangeParameter : Any])
By using the resulting generated secret key I have performed the JWE encryption and got some encrypted string as output. The problem what I am facing it is not decrypting on the server side and server returns "Unable to parse error".
Can anyone let me know, is it the correct way to generate a secret key? What am I doing wrong here?
Thanks
Debugging problems like this is hard. My suggestion is that you pull the problem apart and debug one step at a time. You wrote:
What I am understanding is the secret key generated in Server and iOS side is somehow different.
In that case I recommend that you test that theory specifically. You and your server team should share a pair of private keys (from which you can derive the public keys) and a shared info value, and then each use those to derive a session key. If you get different results, you know that’s the problem.
Having said that, I took a look at your code and it clearly has issues. You’re using the .ecdhKeyExchangeStandard algorithm but you’re also supplying SecKeyKeyExchangeParameter values. The doc comments for kSecKeyAlgorithmECDHKeyExchangeStandard are clear that:
This algorithm does not accept any parameters, length of output raw
shared secret is given by the length of the key.
I suspect your server team is using a different algorithm, one that includes a KDF, but it’s hard to say which one based on the info you’ve presented so far.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"