Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FF129 SubtleCrypto - support for Ed25519 #34989

Merged
merged 34 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b85cd5d
FF129 SubtlCrypto - support for Ed25519
hamishwillee Jul 23, 2024
18e3861
Web Crypto API overview - list interfaces
hamishwillee Jul 29, 2024
bb16d24
Add params for ED25519 and X25519 on the methods that use it
hamishwillee Jul 29, 2024
dcd0105
Update files/en-us/web/api/subtlecrypto/sign/index.md
hamishwillee Jul 29, 2024
1ab1438
Prettier sign()
hamishwillee Jul 29, 2024
16f10d2
Update files/en-us/web/api/subtlecrypto/index.md
hamishwillee Aug 2, 2024
cc9e3da
Update files/en-us/web/api/subtlecrypto/index.md
hamishwillee Aug 2, 2024
27fa5b4
Update files/en-us/web/api/subtlecrypto/derivekey/index.md
hamishwillee Aug 2, 2024
7c6911e
Update files/en-us/web/api/subtlecrypto/generatekey/index.md
hamishwillee Aug 2, 2024
102fa60
Update files/en-us/web/api/subtlecrypto/importkey/index.md
hamishwillee Aug 2, 2024
75a4027
Make algorithm consistent
hamishwillee Aug 2, 2024
8f96284
Consistent heading levels for sign() algorithm info
hamishwillee Aug 2, 2024
db3ae2c
Fix up the algorithm/method table
hamishwillee Aug 2, 2024
7e44156
Fix number algorithms
hamishwillee Aug 2, 2024
7ce4301
X25519 - how to use with deriveKey and deriveBits
hamishwillee Aug 2, 2024
e411874
Update files/en-us/web/api/subtlecrypto/derivekey/index.md
hamishwillee Aug 2, 2024
f596ae6
Fix missing . in EcdhKeyDeriveParams
hamishwillee Aug 2, 2024
e3f2774
Add note to SubtleCrptyo index about the reason for the name
hamishwillee Aug 2, 2024
0c6d31d
Remove duplicate AES in generatekey
hamishwillee Aug 2, 2024
38e21a8
Fix Ed25519 case typo
hamishwillee Aug 2, 2024
7b7f25c
Remove last instance of high performance when describing algorithms
hamishwillee Aug 2, 2024
3eba474
Apply suggestions from code review
hamishwillee Aug 2, 2024
d152975
Fix sign example overflow
hamishwillee Aug 2, 2024
612e1be
Update files/en-us/web/api/subtlecrypto/sign/index.md
wbamberg Aug 2, 2024
ce31bd2
deriveKey - separate algos by key-derivation/agreement heading
hamishwillee Aug 5, 2024
de52774
No one expects the spanish inquisition
hamishwillee Aug 5, 2024
0275474
Apply suggestions from code review
hamishwillee Aug 5, 2024
9a03b1d
sign() - add back preamble for algos
hamishwillee Aug 5, 2024
f12a884
Fix example scrolling + add run button to generate()
hamishwillee Aug 5, 2024
22daadc
Truncate encoded data
hamishwillee Aug 5, 2024
aeccba8
Merge branch 'main' into ff129subtlcrypto_Ed25519
hamishwillee Aug 5, 2024
1e3139a
Update files/en-us/web/api/subtlecrypto/sign/index.md
hamishwillee Aug 6, 2024
b6f9f9a
Apply suggestions from code review
hamishwillee Aug 6, 2024
947664f
Apply suggestions from code review
hamishwillee Aug 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions files/en-us/web/api/subtlecrypto/derivekey/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,40 +86,38 @@ The promise is rejected when one of the following exceptions are encountered:

## Supported algorithms

The three algorithms supported by `deriveKey()` have quite different
characteristics and are appropriate in different situations.
The three algorithms supported by `deriveKey()` have quite different characteristics and are appropriate in different situations.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

### ECDH

ECDH (Elliptic Curve Diffie-Hellman) is a _key-agreement algorithm_. It enables
two people who each have an ECDH public/private key pair to generate a shared secret:
that is, a secret that they — and no one else — share. They can then use this shared
secret as a symmetric key to secure their communication, or can use the secret as an
input to derive such a key (for example, using the HKDF algorithm).
ECDH (Elliptic Curve Diffie-Hellman) is a _key-agreement algorithm_. It enables two people who each have an ECDH public/private key pair to generate a shared secret: that is, a secret that they — and no one else — share.
They can then use this shared secret as a symmetric key to secure their communication, or can use the secret as an input to derive such a key (for example, using the HKDF algorithm).

ECDH is specified in [RFC 6090](https://datatracker.ietf.org/doc/html/rfc6090).

### HKDF

HKDF is a _key derivation function_. It's designed to derive key material from
some high-entropy input, such as the output of an ECDH key agreement operation.
HKDF is a _key derivation function_.
It's designed to derive key material from some high-entropy input, such as the output of an ECDH key agreement operation.

It's _not_ designed to derive keys from relatively low-entropy inputs such as
passwords. For that, use PBKDF2.
It's _not_ designed to derive keys from relatively low-entropy inputs such as passwords.
For that, use PBKDF2.

HKDF is specified in [RFC 5869](https://datatracker.ietf.org/doc/html/rfc5869).

### PBKDF2

PBKDF2 is also a _key derivation function_. It's designed to derive key material
from some relatively low-entropy input, such as a password. It derives key material by
applying a function such as HMAC to the input password along with some salt, and
repeating this process many times. The more times the process is repeated, the more
computationally expensive key derivation is: this makes it harder for an attacker to use
brute-force to discover the key using a dictionary attack.
PBKDF2 is also a _key derivation function_. It's designed to derive key material from some relatively low-entropy input, such as a password.
It derives key material by applying a function such as HMAC to the input password along with some salt, and repeating this process many times.
The more times the process is repeated, the more computationally expensive key derivation is: this makes it harder for an attacker to use brute-force to discover the key using a dictionary attack.

PBKDF2 is specified in [RFC 2898](https://datatracker.ietf.org/doc/html/rfc2898).

#### X25519
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

X25519 is a high-performance key agreement algorithm built on the [Curve25519](https://en.wikipedia.org/wiki/Curve25519) elliptic curve, which is part of the Edwards-Curve Digital Signature Algorithm (EdDSA) family of algorithms defined in {{rfc("8032")}}.
The algorithm is specified in {{rfc("7748")}}.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

## Examples

> [!NOTE]
Expand Down
130 changes: 102 additions & 28 deletions files/en-us/web/api/subtlecrypto/generatekey/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ browser-compat: api.SubtleCrypto.generateKey

{{APIRef("Web Crypto API")}}{{SecureContext_header}}

Use the **`generateKey()`** method of the
{{domxref("SubtleCrypto")}} interface to generate a new key (for symmetric algorithms)
or key pair (for public-key algorithms).
The **`generateKey()`** method of the {{domxref("SubtleCrypto")}} interface is used to generate a new key (for symmetric algorithms) or key pair (for public-key algorithms).

## Syntax

Expand All @@ -25,48 +23,56 @@ generateKey(algorithm, extractable, keyUsages)
- : An object defining the type of key to generate and providing extra algorithm-specific parameters.

- For [RSASSA-PKCS1-v1_5](/en-US/docs/Web/API/SubtleCrypto/sign#rsassa-pkcs1-v1_5), [RSA-PSS](/en-US/docs/Web/API/SubtleCrypto/sign#rsa-pss),
or [RSA-OAEP](/en-US/docs/Web/API/SubtleCrypto/encrypt#rsa-oaep):
or [RSA-OAEP](/en-US/docs/Web/API/SubtleCrypto/encrypt#rsa-oaep)
pass an [`RsaHashedKeyGenParams`](/en-US/docs/Web/API/RsaHashedKeyGenParams) object.
- For [ECDSA](/en-US/docs/Web/API/SubtleCrypto/sign#ecdsa) or [ECDH](/en-US/docs/Web/API/SubtleCrypto/deriveKey#ecdh):
- For [ECDSA](/en-US/docs/Web/API/SubtleCrypto/sign#ecdsa) or [ECDH](/en-US/docs/Web/API/SubtleCrypto/deriveKey#ecdh)
pass an [`EcKeyGenParams`](/en-US/docs/Web/API/EcKeyGenParams) object.
- For [HMAC](/en-US/docs/Web/API/SubtleCrypto/sign#hmac):
pass an [`HmacKeyGenParams`](/en-US/docs/Web/API/HmacKeyGenParams) object.
- For [HMAC](/en-US/docs/Web/API/SubtleCrypto/sign#hmac) — pass an [`HmacKeyGenParams`](/en-US/docs/Web/API/HmacKeyGenParams) object.
- For [AES-CTR](/en-US/docs/Web/API/SubtleCrypto/encrypt#aes-ctr), [AES-CBC](/en-US/docs/Web/API/SubtleCrypto/encrypt#aes-cbc),
[AES-GCM](/en-US/docs/Web/API/SubtleCrypto/encrypt#aes-gcm), or [AES-KW](/en-US/docs/Web/API/SubtleCrypto/wrapKey#aes-kw):
[AES-GCM](/en-US/docs/Web/API/SubtleCrypto/encrypt#aes-gcm), or [AES-KW](/en-US/docs/Web/API/SubtleCrypto/wrapKey#aes-kw)
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
pass an [`AesKeyGenParams`](/en-US/docs/Web/API/AesKeyGenParams) object.
- For [AES-CTR](/en-US/docs/Web/API/SubtleCrypto/encrypt#aes-ctr), [AES-CBC](/en-US/docs/Web/API/SubtleCrypto/encrypt#aes-cbc),
[AES-GCM](/en-US/docs/Web/API/SubtleCrypto/encrypt#aes-gcm), or [AES-KW](/en-US/docs/Web/API/SubtleCrypto/wrapKey#aes-kw) —
pass an [`AesKeyGenParams`](/en-US/docs/Web/API/AesKeyGenParams) object.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
- For the [ED25519](/en-US/docs/Web/API/SubtleCrypto/sign#ed25519) signature algorithm — pass an object of the form: `{ name: "Ed25519"}`.
bsmth marked this conversation as resolved.
Show resolved Hide resolved
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
- For the [X25519](/en-US/docs/Web/API/SubtleCrypto/sign#ed25519) ey agreement algorithm algorithm — pass an object of the form: `{name: 'X25519'}`.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

- `extractable`
- : A boolean value indicating whether it
will be possible to export the key using {{domxref("SubtleCrypto.exportKey()")}} or
{{domxref("SubtleCrypto.wrapKey()")}}.
- : A boolean value indicating whether it will be possible to export the key using {{domxref("SubtleCrypto.exportKey()")}} or {{domxref("SubtleCrypto.wrapKey()")}}.
- `keyUsages`
- : An {{jsxref("Array")}} indicating what can be
done with the newly generated key. Possible values for array elements are:
- `encrypt`: The key may be used to [encrypt](/en-US/docs/Web/API/SubtleCrypto/encrypt) messages.
- `decrypt`: The key may be used to [decrypt](/en-US/docs/Web/API/SubtleCrypto/decrypt) messages.
- `sign`: The key may be used to [sign](/en-US/docs/Web/API/SubtleCrypto/sign) messages.
- `verify`: The key may be used to [verify](/en-US/docs/Web/API/SubtleCrypto/verify) signatures.
- `deriveKey`: The key may be used in [deriving a new key](/en-US/docs/Web/API/SubtleCrypto/deriveKey).
- `deriveBits`: The key may be used in [deriving bits](/en-US/docs/Web/API/SubtleCrypto/deriveBits).
- `wrapKey`: The key may be used to [wrap a key](/en-US/docs/Web/API/SubtleCrypto/wrapKey).
- `unwrapKey`: The key may be used to [unwrap a key](/en-US/docs/Web/API/SubtleCrypto/unwrapKey).

- : An {{jsxref("Array")}} of strings indicating what can be done with the newly generated key.
Possible values for array elements are:

- `encrypt`
- : The key may be used to {{domxref("SubtleCrypto.encrypt()", "encrypt")}} messages.
- `decrypt`
- : The key may be used to {{domxref("SubtleCrypto.decrypt()", "decrypt")}} messages.
- `sign`
- : The key may be used to {{domxref("SubtleCrypto.sign()", "sign")}} messages.
- `verify`
- : The key may be used to {{domxref("SubtleCrypto.verify()", "verify")}} signatures.
- `deriveKey`
- : The key may be used in {{domxref("SubtleCrypto.deriveKey()", "deriving a new key")}}.
- `deriveBits`
- : The key may be used in {{domxref("SubtleCrypto.deriveBits()", "deriving bits")}}.
- `wrapKey`
- : The key may be used to {{domxref("SubtleCrypto.wrapKey()", "wrap a key")}}.
- `unwrapKey`
- : The key may be used to {{domxref("SubtleCrypto.unwrapKey()", "unwrap a key")}}.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

### Return value

A {{jsxref("Promise")}} that fulfills with a
{{domxref("CryptoKey")}} (for symmetric algorithms) or a {{domxref("CryptoKeyPair")}}
(for public-key algorithms).
A {{jsxref("Promise")}} that fulfills with a {{domxref("CryptoKey")}} (for symmetric algorithms) or a {{domxref("CryptoKeyPair")}} (for public-key algorithms).

### Exceptions

The promise is rejected when the following exception is encountered:

- `SyntaxError` {{domxref("DOMException")}}
- : Raised when the result is a {{domxref("CryptoKey")}} of type `secret` or
`private` but `keyUsages` is empty.
- : Raised when the result is a {{domxref("CryptoKey")}} of type `secret` or `private` but `keyUsages` is empty.
- `SyntaxError` {{domxref("DOMException")}}
- : Raised when the result is a {{domxref("CryptoKeyPair")}} and its
`privateKey.usages` attribute is empty.
- : Raised when the result is a {{domxref("CryptoKeyPair")}} and its `privateKey.usages` attribute is empty.

## Examples

Expand Down Expand Up @@ -139,6 +145,74 @@ let key = await window.crypto.subtle.generateKey(
);
```

### Ed25519 key generation

This code generates an Ed25519 signing key pair.
It is derived from [this source code on GitHub.](https://github.com/mdn/dom-examples/blob/main/web-crypto/sign-verify/ed25519.js), which you can [run live here](https://mdn.github.io/dom-examples/web-crypto/sign-verify/).
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

```html hidden
<pre id="log"></pre>
```

```css hidden
#log {
height: 170px;
overflow: scroll;
padding: 0.5rem;
border: 1px solid black;
}
```

```js hidden
const logElement = document.querySelector("#log");
function log(text) {
logElement.innerText = `${logElement.innerText}${text}\n`;
logElement.scrollTop = logElement.scrollHeight;
}
```

#### JavaScript

Code for generating a key pair using the `Ed25519` algorithm and logging the information in each key is shown below.
Note that the code is run in a `try..catch` block because not all browsers support this algorithm.

```js
async function test() {
try {
// Create a key pair and use destructuring assignment to assign to variables
const { publicKey, privateKey } = await crypto.subtle.generateKey(
{
name: "Ed25519",
},
true,
["sign", "verify"],
);

// Log the properties of the keys
log(`publicKey: ${publicKey}`);
log(` type: ${publicKey.type}`);
log(` extractable: ${publicKey.extractable}`);
log(` algorithm: ${JSON.stringify(publicKey.algorithm)}`);
log(` usages: ${publicKey.usages}`);
log(`privateKey: ${privateKey}`);
log(` type: ${privateKey.type}`);
log(` extractable: ${privateKey.extractable}`);
log(` algorithm: ${JSON.stringify(privateKey.algorithm)}`);
log(` usages: ${privateKey.usages}`);
} catch (error) {
log(error);
}
}

test();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is picky, and very optional, but I don't much like live samples that run when the page runs, then you can never run again. To me it breaks the link between the code and the result, it might as well just be a canned response. So I'd always rather give the user a button to push (and a "reset" button) so they can see the code running when they are ready.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is like a canned response, and I'm OK with that because at least it is a "live" response that shows things are working.
That said, I have added a run button that you can use here, and if you click it again it will run again - though since it will produce the same result that won't be interesting.

```

#### Result

The information about the created keys is logged below (or an error string if the browser does not allow the key to be created).

{{EmbedLiveSample("Ed25519", "100%", "230px")}}

## Specifications

{{Specifications}}
Expand Down
5 changes: 3 additions & 2 deletions files/en-us/web/api/subtlecrypto/importkey/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ importKey(format, keyData, algorithm, extractable, keyUsages)
Pass the string identifying the algorithm or an object of the form `{ "name": ALGORITHM }`, where `ALGORITHM` is the name of the algorithm.
- For [PBKDF2](/en-US/docs/Web/API/SubtleCrypto/deriveKey#pbkdf2): Pass the string `PBKDF2`.
- For [HKDF](/en-US/docs/Web/API/SubtleCrypto/deriveKey#hkdf): Pass the string `HKDF`.
- For [Ed25519](#ed25519): Pass an object of the form `{ "name": "Ed25519" }`.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
- For [X25519](/en-US/docs/Web/API/SubtleCrypto/sign#ed25519): Pass an object of the form: `{name: 'X25519'}`.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved
- `extractable`
- : A boolean value indicating whether it will be possible to export the key
using {{domxref("SubtleCrypto.exportKey()")}} or {{domxref("SubtleCrypto.wrapKey()")}}.
- : A boolean value indicating whether it will be possible to export the key using {{domxref("SubtleCrypto.exportKey()")}} or {{domxref("SubtleCrypto.wrapKey()")}}.
- `keyUsages`
- : An {{jsxref("Array")}} indicating what can be done with the key. Possible array values are:
- `encrypt`: The key may be used to [encrypt](/en-US/docs/Web/API/SubtleCrypto/encrypt) messages.
Expand Down
Loading