or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdbrowser-support.mddata-encoding.mderror-handling.mdindex.mdregistration.mdserver.md

data-encoding.mddocs/

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.