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

Introducing crypto section since WebCrypto module has been promoted #1886

Merged
merged 4 commits into from
Mar 27, 2025
Merged
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions docs/sources/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -46,5 +46,6 @@ module.exports = {
clearInterval: 'readonly',
setTimeout: 'readonly',
clearTimeout: 'readonly',
crypto: 'readonly',
},
};
4 changes: 4 additions & 0 deletions docs/sources/k6/next/javascript-api/_index.md
Original file line number Diff line number Diff line change
@@ -77,6 +77,10 @@ The [`k6/browser` module](https://grafana.com/docs/k6/<K6_VERSION>/javascript-ap

{{< docs/shared source="k6" lookup="javascript-api/k6-ws.md" version="<K6_VERSION>" >}}

## crypto

{{< docs/shared source="k6" lookup="javascript-api/crypto.md" version="<K6_VERSION>" >}}

## Error codes

The following specific error codes are currently defined:
90 changes: 90 additions & 0 deletions docs/sources/k6/next/javascript-api/crypto/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
title: 'crypto'
description: 'k6 WebCrypto API implementation'
weight: 14
---

# crypto

With this module, you can use the [WebCrypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) in your k6 scripts. However, note that this API is not yet fully implemented and some algorithms and features might still be missing.

The Web Crypto API is a JavaScript API for performing cryptographic operations such as encryption, decryption, digital signature generation and verification, and key generation and management. It provides a standard interface to access cryptographic functionality, which can help ensure that cryptographic operations are performed correctly and securely.

## API

The module is a top-level `crypto` object with the following properties and methods:

| Interface/Function | Description |
| :------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [getRandomValues](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/getrandomvalues) | Fills the passed `TypedArray` with cryptographically sound random values. |
| [randomUUID](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/randomuuid) | Returns a randomly generated, 36 character long v4 UUID. |
| [subtle](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto) | The [SubtleCrypto](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto) interface provides access to common cryptographic primitives, such as hashing, signing, encryption, or decryption. |

## Example

{{< code >}}

```javascript
export default async function () {
const plaintext = stringToArrayBuffer('Hello, World!');

/**
* Generate a symmetric key using the AES-CBC algorithm.
*/
const key = await crypto.subtle.generateKey(
{
name: 'AES-CBC',
length: 256,
},
true,
['encrypt', 'decrypt']
);

/**
* Encrypt the plaintext using the AES-CBC key with
* have generated.
*/
const iv = crypto.getRandomValues(new Uint8Array(16));
const ciphertext = await crypto.subtle.encrypt(
{
name: 'AES-CBC',
iv: iv,
},
key,
plaintext
);

/**
* Decrypt the ciphertext using the same key to verify
* that the resulting plaintext is the same as the original.
*/
const deciphered = await crypto.subtle.decrypt(
{
name: 'AES-CBC',
iv: iv,
},
key,
ciphertext
);

console.log(
'deciphered text == original plaintext: ',
arrayBufferToHex(deciphered) === arrayBufferToHex(plaintext)
);
}

function arrayBufferToHex(buffer) {
return [...new Uint8Array(buffer)].map((x) => x.toString(16).padStart(2, '0')).join('');
}

function stringToArrayBuffer(str) {
const buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
const bufView = new Uint16Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
```

{{< /code >}}
64 changes: 64 additions & 0 deletions docs/sources/k6/next/javascript-api/crypto/aescbcparams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: 'AesCbcParams'
description: 'AesCbcParams represents the object that should be passed as the algorithm parameter into the encrypt and decrypt operation when using the AES-CBC algorithm.'
weight: 04
---

# AesCbcParams

The `AesCbcParams` object represents the object that should be passed as the algorithm parameter into the [encrypt](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/encrypt) and [decrypt](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/decrypt) operation when using the AES-CBC algorithm.

For more details, head to the [MDN Web Crypto API documentation on AES-CBC](https://developer.mozilla.org/en-US/docs/Web/API/AesCbcParams).

## Properties

| Property | Type | Description |
| :------- | :----------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | `string` | Should be set to `AES-CBC`. |
| iv | `ArrayBuffer`, `TypedArray`, or `DataView` | The initialization vector. Must be 16 bytes, unpredictable and cryptographically random. Yet, it doesn't need to be secret and can be transmitted along with the ciphertext. |

## Example

{{< code >}}

```javascript
export default async function () {
const plaintext = stringToArrayBuffer('Hello, World!');

/**
* Generate a symmetric key using the AES-CBC algorithm.
*/
const key = await crypto.subtle.generateKey(
{
name: 'AES-CBC',
length: 256,
},
true,
['encrypt', 'decrypt']
);

/**
* Encrypt the plaintext using the AES-CBC key with
* have generated.
*/
const ciphertext = await crypto.subtle.encrypt(
{
name: 'AES-CBC',
iv: crypto.getRandomValues(new Uint8Array(16)),
},
key,
plaintext
);
}

function stringToArrayBuffer(str) {
const buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
const bufView = new Uint16Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
```

{{< /code >}}
66 changes: 66 additions & 0 deletions docs/sources/k6/next/javascript-api/crypto/aesctrparams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: 'AesCtrParams'
description: 'AesCtrParams represents the object that should be passed as the algorithm parameter into the encrypt and decrypt operation when using the AES-CTR algorithm.'
weight: 05
---

# AesCtrParams

The `AesCtrParams` object represents the object that should be passed as the algorithm parameter into the [encrypt](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/encrypt) and [decrypt](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/decrypt) operation when using the AES-CTR algorithm.

For more details, head to the MDN Web Crypto API documentation on [AES-CTR](https://developer.mozilla.org/en-US/docs/Web/API/AesCtrParams).

## Properties

| Property | Type | Description |
| :------- | :----------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------- |
| name | `string` | Should be set to `AES-CTR`. |
| counter | `ArrayBuffer`, `TypedArray`, or `DataView` | The initial value of the counter block. This must be 16-bytes long, like the AES block size. |
| length | `number` | The number of bits in the counter block that are used for the actual counter. It is recommended to use 64 (half of the counter block). |

## Example

{{< code >}}

```javascript
export default async function () {
const plaintext = stringToArrayBuffer('Hello, World!');

/**
* Generate a symmetric key using the AES-CTR algorithm.
*/
const key = await crypto.subtle.generateKey(
{
name: 'AES-CTR',
length: 256,
},
true,
['encrypt', 'decrypt']
);

/**
* Encrypt the plaintext using the AES-CTR key with
* have generated.
*/
const ciphertext = await crypto.subtle.encrypt(
{
name: 'AES-CTR',
counter: crypto.getRandomValues(new Uint8Array(16)),
length: 128,
},
key,
plaintext
);
}

function stringToArrayBuffer(str) {
const buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
const bufView = new Uint16Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
```

{{< /code >}}
66 changes: 66 additions & 0 deletions docs/sources/k6/next/javascript-api/crypto/aesgcmparams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: 'AesGcmParams'
description: 'AesGcmParams represents the object that should be passed as the algorithm parameter into the encrypt and decrypt operation when using the AES-GCM algorithm.'
weight: 06
---

# AesGcmParams

The `AesGcmParams` object represents the object that should be passed as the algorithm parameter into the [encrypt](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/encrypt) and [decrypt](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/decrypt) operation when using the AES-GCM algorithm.

For more details, head to the [MDN Web Crypto API documentation on AES-GCM](https://developer.mozilla.org/en-US/docs/Web/API/AesGcmParams).

## Properties

| Property | Type | Description |
| :------------------------ | :----------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | `string` | Should be set to `AES-GCM`. |
| iv | `ArrayBuffer`, `TypedArray`, or `DataView` | The initialization vector. It must be 12 bytes long, unpredictable and cryptographically random. It must be unique for every encryption operation carried out with a given key. Never reuse an iv with the same key. Yet, it doesn't need to be secret and can be transmitted along with the ciphertext. |
| additionalData (optional) | `ArrayBuffer`, `TypedArray` or `DataView` | Additional data that should be authenticated, but not encrypted. It must be included in the calculation of the authentication tag, but not encrypted itself. |
| tagLength (optional) | `number` | The length of the authentication tag in bits. Should be set, and will default to 96. |

## Example

{{< code >}}

```javascript
export default async function () {
const plaintext = stringToArrayBuffer('Hello, World!');

/**
* Generate a symmetric key using the AES-CBC algorithm.
*/
const key = await crypto.subtle.generateKey(
{
name: 'AES-GCM',
length: 256,
},
true,
['encrypt', 'decrypt']
);

/**
* Encrypt the plaintext using the AES-CBC key with
* have generated.
*/
const ciphertext = await crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: crypto.getRandomValues(new Uint8Array(12)),
},
key,
plaintext
);
}

function stringToArrayBuffer(str) {
const buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
const bufView = new Uint16Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
```

{{< /code >}}
35 changes: 35 additions & 0 deletions docs/sources/k6/next/javascript-api/crypto/aeskeygenparams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: 'AesKeyGenParams'
description: 'AesKeyGenParams represents the object that should be passed as the algorithm parameter into the generateKey operation, when generating an AES key.'
weight: 07
---

# AesKeyGenParams

The `AesKeyGenParams` object represents the object that should be passed as the algorithm parameter into the [generateKey](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/generatekey) operation when generating an AES key.

## Properties

| Property | Type | Description |
| :------- | :------- | :---------------------------------------------------------------------------------- |
| name | `string` | The name of the algorithm. Possible values are `AES-CBC`, `AES-CTR`, and `AES-GCM`. |
| length | `number` | The length of the key in bits. Possible values are 128, 192 or 256. |

## Example

{{< code >}}

```javascript
export default async function () {
const key = await crypto.subtle.generateKey(
{
name: 'AES-CBC',
length: 256,
},
true,
['encrypt', 'decrypt']
);
}
```

{{< /code >}}
18 changes: 18 additions & 0 deletions docs/sources/k6/next/javascript-api/crypto/cryptokey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: 'CryptoKey'
description: 'CryptoKey represents a cryptographic key used for encryption, decryption, signing, or verification.'
weight: 02
---

# CryptoKey

The `CryptoKey` object represents a cryptographic key used for [encryption](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/encrypt),[decryption](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/decrypt),[signing](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/sign), or [verification](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/verify) within the webcrypto module. The `CryptoKey` object is created using the SubtleCrypto.generateKey() or SubtleCrypto.importKey() methods.

## Properties

| Property | Type | Description |
| :---------- | :--------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type | `string` | Indicates the type of the key material. Possible values are `public`, `private`, `secret`, `unspecified`, or `unknown`. |
| extractable | `boolean` | Indicates whether the raw key material can be exported. |
| algorithm | `object` | An object containing the algorithm used to generate or import the key. |
| usages | `string[]` | An array of strings indicating the cryptographic operations that the key can be used for. Possible values are `encrypt`, `decrypt`, `sign`, `verify`, `deriveKey`, `deriveBits`, `wrapKey`, and `unwrapKey`. |
18 changes: 18 additions & 0 deletions docs/sources/k6/next/javascript-api/crypto/cryptokeypair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: 'CryptoKeyPair'
description: 'CryptoKeyPair represents an asymmetric key pair with public and private keys.'
weight: 08
---

# CryptoKeyPair

The `CryptoKeyPair` object represents an asymmetric key pair with public and private keys.

The [`generateKey`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/subtlecrypto/generatekey/) method can be used to create `CryptoKeyPair` object for asymmetric algorithms such as `ECDH` or `ECDSA`.

## Properties

| Property | Type | Description |
| :--------- | :-------------------------------------------------------------------------------------- | :------------- |
| publicKey | [`CryptoKey`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/cryptokey) | A public key. |
| privateKey | [`CryptoKey`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/crypto/cryptokey) | A private key. |
Loading