0

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)")
        }
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
Gorthez
  • 391
  • 3
  • 12
  • 1
    You're missing the entire HKDF part in Java. Have you tried to implement the key derivation using HKDF already? – Maarten Bodewes Mar 23 '21 at 20:16
  • @MaartenBodewes You mean in Java? No, I didn't. I will ask backend for that. Do you think is it possible to do it without HKDF? – Gorthez Mar 24 '21 at 09:00
  • 1
    No, because your `hkdfDerivedSymmetricKey` method call in iOS. Unfortunately that method doesn't specify how the ECDH coordinate result is used as IKM for HKDF, but I would guess that it just uses the X-coordinate in unsigned big endian form. – Maarten Bodewes Mar 24 '21 at 09:11

0 Answers0