1

I'm generating the Public and Private key by using the Native Browser crypto API as below:

export const generateKeyPair = async (): Promise<CryptoKeyPair> => {
    return await window.crypto.subtle.generateKey(
        {
            name: "ECDH",
            namedCurve: "P-384",
        },
        true,
        ["deriveKey", "deriveBits"],
    );
};

Then I'll export the publicKey by using the exportKey function under the window.crypto.subtle as below:

const keyPair: CryptoKeyPair = yield generateKeyPair();
const publicKeyArrayBuffer: ArrayBuffer = yield window.crypto.subtle.exportKey("raw", keyPair.publicKey);
const publicKeyAsBase64 = arrayBufferToBase64(publicKeyArrayBuffer);

If you have any suggestions, please let me know and help me to fix this issue.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Ali Torki
  • 1,929
  • 16
  • 26
  • 1
    Maybe the Java code expects the key in a different format. Post the Java code and also an example of a key exported with the JavaScript code. – Topaco Aug 31 '21 at 20:17
  • Thanks for commenting, This is an example of the javascript code result: BNCGjPDvjrzqqVSAru54rWN0OVYfq/98EC6O+UH/mId965tsdZbccQDXIKvUBAxq5Q7DhTnp4nDfNp9lSbo99i8MXdbaPV3iA7bB39+zhzUWEEnkfQdzrAF3cWUq7RWRRw== – Ali Torki Aug 31 '21 at 20:20
  • Unfortunately I've no access to the Backend's code – Ali Torki Aug 31 '21 at 20:21
  • 1
    The key is an uncompressed EC key: 0x04||. Keys can be specified in different formats. You have to find out the required format of the Java code somehow. Of course you can also try common formats, e.g. X.509/SPKI. – Topaco Aug 31 '21 at 20:25
  • I updated the question, Please check it out. – Ali Torki Sep 01 '21 at 09:37
  • The public key should be in ASN1 format which is finally converted to Base64 for sending to the Server and receive the Server publicKey. – Ali Torki Sep 01 '21 at 10:37
  • 1
    `X509EncodedKeySpec()` corresponds to the X.509/SPKI format, DER encoded. `exportKey()` supports the spki format (s. e.g. [here](https://github.com/diafygi/webcrypto-examples#ecdh---exportkey)). – Topaco Sep 01 '21 at 12:40
  • This is an Example of valid publicKey and if I send it to the Backend, it will response me a publicKey `MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmDOvSajZFQT261yTdkE0EloJ8AP4gJKO7kDLNnNlT9fLHuWhl+shys58xCdT4ABtPZOSNtyTRQNh1rDvIkp3EA==`. And I also tried using the `spki` and it doesn't work. – Ali Torki Sep 01 '21 at 13:18
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236652/discussion-between-ali-torki-and-topaco). – Ali Torki Sep 01 '21 at 14:03

1 Answers1

1

Both codes use different curves, the Java code secp256r1 (aka P-256), the JavaScript code P-384. To make both codes compatible, the JavaScript code must apply the same curve as the Java code, i.e. P-256 (s. also here).

The Java code exports a public EC key in X.509/SPKI format, which is Base64 encoded. The JavaScript code exports the public key in uncompressed format 0x04|<x>|<y>. The export in X.509/SPKI format is possible with spki as 1st parameter, s. here and here.

Topaco
  • 40,594
  • 4
  • 35
  • 62
  • Do you know how can I encrypt a string with the `serverPublicKey`(which is a base64 string) and my `privateKey` by AES-256? and also the decryption process? I really appreciate your help. – Ali Torki Sep 03 '21 at 21:37
  • 1
    This cannot be answered in the context of a comment. Please post a new question on SO with all the necessary information. If needed, you can reference this post. – Topaco Sep 04 '21 at 06:15