aboutsummaryrefslogtreecommitdiff
path: root/docs/api/hashing.md
blob: 13d09dbfe7884fbd311f2e751890d98d55734c73 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
{% callout %}

Bun implements the `createHash` and `createHmac` functions from [`node:crypto`](https://nodejs.org/api/crypto.html) in addition to the Bun-native APIs documented below.

{% /callout %}

## `Bun.password`

`Bun.password` is a collection of utility functions for hashing and verifying passwords with various cryptographically secure algorithms.

```ts
const password = "super-secure-pa$$word";

const hash = await Bun.password.hash(password);
// => $argon2id$v=19$m=65536,t=2,p=1$tFq+9AVr1bfPxQdh6E8DQRhEXg/M/SqYCNu6gVdRRNs$GzJ8PuBi+K+BVojzPfS5mjnC8OpLGtv8KJqF99eP6a4

const isMatch = await Bun.password.verify(password, hash);
// => true
```

The second argument to `Bun.password.hash` accepts a params object that lets you pick and configure the hashing algorithm.

```ts
const password = "super-secure-pa$$word";

// use argon2 (default)
const argonHash = await Bun.password.hash(password, {
  algorithm: "argon2id", // "argon2id" | "argon2i" | "argon2d"
  memoryCost: 4, // memory usage in kibibytes
  timeCost: 3, // the number of iterations
});

// use bcrypt
const bcryptHash = await Bun.password.hash(password, {
  algorithm: "bcrypt",
  cost: 4, // number between 4-31
});
```

The algorithm used to create the hash is stored in the hash itself. When using `bcrypt`, the returned hash is encoded in [Modular Crypt Format](https://passlib.readthedocs.io/en/stable/modular_crypt_format.html) for compatibility with most existing `bcrypt` implementations; with `argon2` the result is encoded in the newer [PHC format](https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md).

The `verify` function automatically detects the algorithm based on the input hash and use the correct verification method. It can correctly infer the algorithm from both PHC- or MCF-encoded hashes.

```ts
const password = "super-secure-pa$$word";

const hash = await Bun.password.hash(password, {
  /* config */
});

const isMatch = await Bun.password.verify(password, hash);
// => true
```

Synchronous versions of all functions are also available. Keep in mind that these functions are computationally expensive, so using a blocking API may degrade application performance.

```ts
const password = "super-secure-pa$$word";

const hash = Bun.password.hashSync(password, {
  /* config */
});

const isMatch = Bun.password.verifySync(password, hash);
// => true
```

## `Bun.hash`

`Bun.hash` is a collection of utilities for _non-cryptographic_ hashing. Non-cryptographic hashing algorithms are optimized for speed of computation over collision-resistance or security.

The standard `Bun.hash` functions uses [Wyhash](https://github.com/wangyi-fudan/wyhash) to generate a 64-bit hash from an input of arbitrary size.

```ts
Bun.hash("some data here");
// 11562320457524636935n
```

The input can be a string, `TypedArray`, `DataView`, `ArrayBuffer`, or `SharedArrayBuffer`.

```ts
const arr = new Uint8Array([1, 2, 3, 4]);

Bun.hash("some data here");
Bun.hash(arr);
Bun.hash(arr.buffer);
Bun.hash(new DataView(arr.buffer));
```

Optionally, an integer seed can be specified as the second parameter. For 64-bit hashes seeds above `Number.MAX_SAFE_INTEGER` should be given as BigInt to avoid loss of precision.

```ts
Bun.hash("some data here", 1234);
// 15724820720172937558n
```

Additional hashing algorithms are available as properties on `Bun.hash`. The API is the same for each, only changing the return type from number for 32-bit hashes to bigint for 64-bit hashes.

```ts
Bun.hash.wyhash("data", 1234); // equivalent to Bun.hash()
Bun.hash.crc32("data", 1234);
Bun.hash.adler32("data", 1234);
Bun.hash.cityHash32("data", 1234);
Bun.hash.cityHash64("data", 1234);
Bun.hash.murmur32v3("data", 1234);
Bun.hash.murmur32v2("data", 1234);
Bun.hash.murmur64v2("data", 1234);
```

## `Bun.CryptoHasher`

`Bun.CryptoHasher` is a general-purpose utility class that lets you incrementally compute a hash of string or binary data using a range of cryptographic hash algorithms. The following algorithms are supported:

- `"blake2b256"`
- `"md4"`
- `"md5"`
- `"ripemd160"`
- `"sha1"`
- `"sha224"`
- `"sha256"`
- `"sha384"`
- `"sha512"`
- `"sha512-256"`

```ts
const hasher = new Bun.CryptoHasher("sha256");
hasher.update("hello world");
hasher.digest();
// Uint8Array(32) [ <byte>, <byte>, ... ]
```

Once initialized, data can be incrementally fed to to the hasher using `.update()`. This method accepts `string`, `TypedArray`, and `ArrayBuffer`.

```ts
const hasher = new Bun.CryptoHasher("sha256");

hasher.update("hello world");
hasher.update(new Uint8Array([1, 2, 3]));
hasher.update(new ArrayBuffer(10));
```

If a `string` is passed, an optional second parameter can be used to specify the encoding (default `'utf-8'`). The following encodings are supported:

{% table %}

---

- Binary encodings
- `"base64"` `"base64url"` `"hex"` `"binary"`

---

- Character encodings
- `"utf8"` `"utf-8"` `"utf16le"` `"latin1"`

---

- Legacy character encodings
- `"ascii"` `"binary"` `"ucs2"` `"ucs-2"`

{% /table %}

```ts
hasher.update("hello world"); // defaults to utf8
hasher.update("hello world", "hex");
hasher.update("hello world", "base64");
hasher.update("hello world", "latin1");
```

After the data has been feed into the hasher, a final hash can be computed using `.digest()`. By default, this method returns a `Uint8Array` containing the hash.

```ts
const hasher = new Bun.CryptoHasher("sha256");
hasher.update("hello world");

hasher.digest();
// => Uint8Array(32) [ 185, 77, 39, 185, 147, ... ]
```

The `.digest()` method can optionally return the hash as a string. To do so, specify an encoding:

```ts
hasher.digest("base64");
// => "uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek="

hasher.digest("hex");
// => "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
```

Alternatively, the method can write the hash into a pre-existing `TypedArray` instance. This may be desirable in some performance-sensitive applications.

```ts
const arr = new Uint8Array(32);

hasher.digest(arr);

console.log(arr);
// => Uint8Array(32) [ 185, 77, 39, 185, 147, ... ]
```

<!-- Bun.sha; -->
/td>9-46/+115 * fix(#7923): do not throw on user { type } object * chore: remove unused type export * chore: guess it wasn't unused 2023-08-21[ci] formatGravatar natemoo-re 1-1/+4 2023-08-21fix(dev): open to base path (#8123)Gravatar Nate Moore 2-1/+8 2023-08-21chore(gitpod): resolve potential globbing and word splitting issue (#8124)Gravatar Ben Elan 1-1/+1 Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> 2023-08-21fix(#6965): fix build stats (#8122)Gravatar Nate Moore 2-1/+8 2023-08-21only update our own history entires during back navigation through view ↵Gravatar Martin Trapp 2-3/+11 transitions (#8116) 2023-08-21fix: reinsert attribute to specify direction of ViewTransition (forward / ↵Gravatar Martin Trapp 2-7/+12 back) (#8109) 2023-08-21Remove deprecated APIs (#8170)Gravatar Bjorn Lu 4-107/+5 2023-08-21Remove pre-shiki v0.14 theme names (#8169)Gravatar Bjorn Lu 6-80/+14 2023-08-21[docs] JSX framework integration READMEs (#8151)Gravatar Sarah Rainsberger 3-0/+104 2023-08-21fix(assets): Add missing type for imageConfig export (#8171)Gravatar Erika 2-1/+7 2023-08-21Deprecate simple objects from endpoints (#8132)Gravatar Bjorn Lu 20-201/+243 2023-08-18[docs] update scopedStyleStragegy default and description (#8148)Gravatar Sarah Rainsberger 1-2/+2 2023-08-18[ci] release (#8145)astro@2.10.12@astrojs/react@2.3.2@astrojs/node@5.3.5Gravatar Houston (Bot) 46-92/+98 Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> 2023-08-18Fix missing package file regression (#8149)Gravatar Matthew Phillips 2-1/+7 2023-08-18fix(node): delegate preview's not found and error handling to core/app (#8141)Gravatar Arsh 2-9/+6 * fix(node): delegate preview's not found and error handling to core/app * add changeset --------- Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> 2023-08-18Replace `class:list` implementation with `clsx` (#8142)Gravatar Nate Moore 12-68/+133 * chore: replace `class:list` implementation with `clsx` * chore: remove Set support from `class:list` test * chore: better class:list test * Update packages/astro/src/runtime/server/render/component.ts 2023-08-18[ci] formatGravatar matthewp 1-1/+4 2023-08-18fix(data collections): normalize file paths for DataEntry.id (#8144)Gravatar Arsh 2-1/+6 * normalize file paths for DataEntry.id * add changeset 2023-08-18[ci] release (beta) (#8140)astro@3.0.0-beta.4Gravatar Houston (Bot) 41-65/+72 Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> 2023-08-18[error messages] Update image errors-data.ts (#8126)Gravatar Sarah Rainsberger 1-12/+12 Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> 2023-08-18fix(polyfills): Use object shape for Stackblitz polyfill listGravatar Princesseuh 1-2/+2 2023-08-18fix: polyfill File using undici instead of node:buffer (#8139)Gravatar Erika 2-8/+9 * fix: polyfill File using undici instead of node:buffer * chore: changeset 2023-08-18[ci] release (beta) (#8073)create-astro@4.0.0-beta.1astro@3.0.0-beta.3@astrojs/vercel@4.0.0-beta.3@astrojs/telemetry@3.0.0-beta.2@astrojs/svelte@4.0.0-beta.1@astrojs/solid-js@3.0.0-beta.2@astrojs/react@3.0.0-beta.3@astrojs/mdx@1.0.0-beta.1@astrojs/cloudflare@7.0.0-beta.2Gravatar Houston (Bot) 63-117/+389 Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> 2023-08-18[ci] release (#8138)astro@2.10.11@astrojs/react@2.3.1Gravatar Houston (Bot) 44-80/+82 Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> 2023-08-18[ci] formatGravatar natemoo-re 1-1/+1 2023-08-18Fix 404 response leading to an infinite loop when there is no 404 page (#8136)Gravatar André Alves 2-1/+10 * fix: 404 response leads to infinite loop * chore: changeset --------- Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> 2023-08-18fix(react): add missing export (#8137)Gravatar Nate Moore 2-1/+7 2023-08-18[ci] release (#8096)create-astro@3.2.2astro@2.10.10@astrojs/vercel@3.8.2@astrojs/svelte@3.1.1@astrojs/solid-js@2.2.1@astrojs/react@2.3.0Gravatar Houston (Bot) 63-197/+186 Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> 2023-08-18changeset(next): inlineStylesheets default switch is major (#8133)Gravatar Arsh 1-1/+1 2023-08-18feat: add polyfills for stackblitz (#8130)Gravatar Erika 7-6/+86 * feat: add polyfills for Stackblitz * chore: changeset