I want to create secretKey(symmetricKey) using my EC privateKey and publicKey from backend(Java) and decrypt message using that secretKey. How to achieve this? Here is implementation:
This is how backend creates sharedKey:
KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH", "BC");
keyAgreement.init(privateKey);
keyAgreement.doPhase(publicKey, true);
return keyAgreement.generateSecret("AES");
Here is how iOS creates sharedSecret->SymmetricKey not sure if this is right because comparing secretKeys with backend my key is different (by definition of ECDH should be same)
let serverPubKey = try P256.KeyAgreement.PublicKey(pemRepresentation: serverPublicKeyPEM)
let shared = try privateKey.sharedSecretFromKeyAgreement(with: serverPubKey)
let symetricKey = shared.hkdfDerivedSymmetricKey(using: SHA256.self,
salt: "".data(using: .utf8)!,
sharedInfo: Data(),
outputByteCount: 32)
here is how backend encrypts
byte[] plain = Base64.getEncoder().encodeToString(plainString.getBytes(StandardCharsets.UTF_8)).getBytes();
SecretKey key = generateSharedSecret(decodePrivateKey(sessionKey), decodePublicKey( devicePublicKey));
Cipher encryptor = Cipher.getInstance("AES/CTR/NoPadding", BouncyCastleProvider.PROVIDER_NAME);
IvParameterSpec ivSpec = new IvParameterSpec(INITIALIZATION_VECTOR);
encryptor.init(Cipher.ENCRYPT_MODE, key, ivSpec);
return Base64.getEncoder().encodeToString(encryptor.doFinal(plain, 0, plain.length));
and here is how iOS trying to decrypt
guard let payloadData = Data(base64Encoded: payload) else { return }
do {
//I know that sealedBox is wrong, should be just box? I'm not sure of this step
let sealedBox = try AES.GCM.SealedBox(combined: payloadData)
let decrypted = try AES.GCM.open(sealedBox, using: symmetricKey)
//here I'm getting authenticationFailure
} catch {
print("error: \(error)")
}