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.

Ali Torki
  • 1,810
  • 13
  • 24
  • 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
    Both codes use different curves: secp256r1 (aka P-256) in the Java code and P-384 in the JavaScript code. You must apply the **same** curves, try P-256 in the JavaScript Code. – Topaco Sep 01 '21 at 14:34
  • Please convert your last comment to an answer, because I wanna mark it as `the best answer` – Ali Torki Sep 01 '21 at 19:50
  • 1
    You're welcome, I put my comments as an answer. – Topaco Sep 02 '21 at 07:04

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
  • 28,888
  • 3
  • 20
  • 51
  • 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
  • I asked another question here, may you help me? https://stackoverflow.com/questions/69139123/nodejs-aes-256-crt-decryption – Ali Torki Sep 11 '21 at 00:26