0
# Data Encoding Utilities
1
2
Utilities for converting between Base64URL strings and ArrayBuffers, essential for WebAuthn data handling. WebAuthn APIs use ArrayBuffers, but JSON serialization requires string encoding, making these conversion functions crucial for client-server communication.
3
4
## Capabilities
5
6
### Base64URL String to Buffer
7
8
Converts a Base64URL-encoded string to an ArrayBuffer for use with WebAuthn APIs.
9
10
```typescript { .api }
11
/**
12
* Convert from a Base64URL-encoded string to an Array Buffer. Best used when converting a
13
* credential ID from a JSON string to an ArrayBuffer, like in allowCredentials or
14
* excludeCredentials
15
*
16
* Helper method to compliment `bufferToBase64URLString`
17
* @param base64URLString The Base64URL-encoded string to convert
18
* @returns ArrayBuffer containing the decoded binary data
19
*/
20
function base64URLStringToBuffer(base64URLString: string): ArrayBuffer;
21
```
22
23
**Usage Examples:**
24
25
```typescript
26
import { base64URLStringToBuffer } from "@simplewebauthn/browser";
27
28
// Convert challenge from server JSON to ArrayBuffer for WebAuthn
29
const challengeString = "dGVzdC1jaGFsbGVuZ2U"; // From server JSON
30
const challengeBuffer = base64URLStringToBuffer(challengeString);
31
32
// Convert user ID from server JSON to ArrayBuffer
33
const userIdString = "dXNlci0xMjM0NTY"; // From server JSON
34
const userIdBuffer = base64URLStringToBuffer(userIdString);
35
36
// Convert credential IDs for allowCredentials/excludeCredentials
37
const credentialIds = [
38
"Y3JlZGVudGlhbC0xMjM0NTY",
39
"YW5vdGhlci1jcmVkZW50aWFsLTc4OQ"
40
];
41
42
const allowCredentials = credentialIds.map(id => ({
43
type: "public-key" as const,
44
id: base64URLStringToBuffer(id),
45
transports: ["usb", "nfc", "ble", "hybrid"] as const,
46
}));
47
48
console.log("Converted credential IDs:", allowCredentials);
49
```
50
51
This function handles the Base64URL to Base64 conversion (replacing `-` with `+` and `_` with `/`), adds proper padding, and converts the decoded binary string to an ArrayBuffer via `Uint8Array`.
52
53
### Buffer to Base64URL String
54
55
Converts an ArrayBuffer to a Base64URL-encoded string suitable for JSON serialization and server transmission.
56
57
```typescript { .api }
58
/**
59
* Convert the given array buffer into a Base64URL-encoded string. Ideal for converting various
60
* credential response ArrayBuffers to string for sending back to the server as JSON.
61
*
62
* Helper method to compliment `base64URLStringToBuffer`
63
* @param buffer The ArrayBuffer to convert
64
* @returns Base64URL-encoded string suitable for JSON transmission
65
*/
66
function bufferToBase64URLString(buffer: ArrayBuffer): string;
67
```
68
69
**Usage Examples:**
70
71
```typescript
72
import { bufferToBase64URLString } from "@simplewebauthn/browser";
73
74
// Convert WebAuthn response data for server transmission
75
const credential = await navigator.credentials.create(options);
76
77
const registrationResponse = {
78
id: credential.id,
79
rawId: bufferToBase64URLString(credential.rawId),
80
response: {
81
clientDataJSON: bufferToBase64URLString(credential.response.clientDataJSON),
82
attestationObject: bufferToBase64URLString(credential.response.attestationObject),
83
},
84
type: credential.type,
85
};
86
87
// Send to server as JSON
88
await fetch("/webauthn/register/finish", {
89
method: "POST",
90
headers: { "Content-Type": "application/json" },
91
body: JSON.stringify(registrationResponse),
92
});
93
94
// Convert authentication response data
95
const authCredential = await navigator.credentials.get(authOptions);
96
97
const authResponse = {
98
id: authCredential.id,
99
rawId: bufferToBase64URLString(authCredential.rawId),
100
response: {
101
clientDataJSON: bufferToBase64URLString(authCredential.response.clientDataJSON),
102
authenticatorData: bufferToBase64URLString(authCredential.response.authenticatorData),
103
signature: bufferToBase64URLString(authCredential.response.signature),
104
userHandle: authCredential.response.userHandle
105
? bufferToBase64URLString(authCredential.response.userHandle)
106
: undefined,
107
},
108
};
109
110
console.log("Authentication response:", authResponse);
111
```
112
113
This function converts the ArrayBuffer to a `Uint8Array`, builds a binary string, encodes it with `btoa()`, and then converts from Base64 to Base64URL format (replacing `+` with `-`, `/` with `_`, and removing padding `=` characters).
114
115
## Data Flow in WebAuthn
116
117
These utilities are essential for the WebAuthn data flow:
118
119
```typescript
120
import {
121
base64URLStringToBuffer,
122
bufferToBase64URLString,
123
startRegistration
124
} from "@simplewebauthn/browser";
125
126
// 1. Server sends JSON with Base64URL-encoded data
127
const serverOptions = {
128
challenge: "dGVzdC1jaGFsbGVuZ2U",
129
user: {
130
id: "dXNlci0xMjM0NTY",
131
name: "testuser",
132
displayName: "Test User"
133
},
134
// ... other options
135
};
136
137
// 2. Library converts to WebAuthn format internally
138
const webauthnOptions = {
139
challenge: base64URLStringToBuffer(serverOptions.challenge),
140
user: {
141
...serverOptions.user,
142
id: base64URLStringToBuffer(serverOptions.user.id),
143
},
144
// ... other conversions
145
};
146
147
// 3. WebAuthn API returns ArrayBuffers
148
const credential = await navigator.credentials.create({ publicKey: webauthnOptions });
149
150
// 4. Library converts back to Base64URL for JSON transmission
151
const response = {
152
id: credential.id,
153
rawId: bufferToBase64URLString(credential.rawId),
154
response: {
155
clientDataJSON: bufferToBase64URLString(credential.response.clientDataJSON),
156
attestationObject: bufferToBase64URLString(credential.response.attestationObject),
157
},
158
};
159
160
// 5. Send JSON to server
161
await fetch("/webauthn/register/finish", {
162
method: "POST",
163
headers: { "Content-Type": "application/json" },
164
body: JSON.stringify(response),
165
});
166
```
167
168
## Base64URL vs Base64
169
170
Base64URL is a variant of Base64 encoding that's URL and filename safe:
171
172
- **Base64**: Uses `+`, `/`, and `=` for padding
173
- **Base64URL**: Uses `-`, `_`, and no padding
174
175
WebAuthn specifications use Base64URL encoding for JSON serialization because:
176
177
1. URL-safe characters don't need escaping in URLs or form data
178
2. No padding characters simplify string handling
179
3. Compatible with JSON without special character escaping
180
181
```typescript
182
// Example of the difference:
183
const buffer = new ArrayBuffer(16);
184
const view = new Uint8Array(buffer);
185
view.set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
186
187
// Standard Base64 (hypothetical)
188
// "AQIDBAUGBwgJCgsMDQ4PEA=="
189
190
// Base64URL (actual result)
191
// "AQIDBAUGBwgJCgsMDQ4PEA"
192
const base64url = bufferToBase64URLString(buffer);
193
console.log("Base64URL:", base64url); // No padding, URL-safe chars
194
```
195
196
## Performance Considerations
197
198
These functions are optimized for typical WebAuthn data sizes:
199
200
- **Challenges**: Usually 32-64 bytes
201
- **User IDs**: Usually 8-64 bytes
202
- **Credential IDs**: Usually 16-255 bytes
203
- **Signatures**: Usually 64-256 bytes
204
- **Public Keys**: Usually 65-133 bytes
205
206
For large data sets, consider streaming approaches, but WebAuthn data rarely exceeds a few KB per operation.
207
208
## Error Handling
209
210
Both functions are designed to be robust:
211
212
```typescript
213
try {
214
const buffer = base64URLStringToBuffer(invalidString);
215
} catch (error) {
216
console.error("Invalid Base64URL string:", error);
217
}
218
219
try {
220
const string = bufferToBase64URLString(buffer);
221
console.log("Conversion successful:", string);
222
} catch (error) {
223
console.error("Buffer conversion failed:", error);
224
}
225
```
226
227
The functions will throw standard JavaScript errors for invalid inputs like malformed Base64URL strings or invalid ArrayBuffers.