or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

asymmetric-cryptography.mdcrypto-interface.mdhash-functions.mdindex.mdkey-derivation.mdmodern-cryptography.mdsymmetric-encryption.md

key-derivation.mddocs/

0

# Key Derivation

1

2

Key derivation functions for generating cryptographic keys from passwords, shared secrets, or other key material. Supports PBKDF2, HKDF, and HMAC operations.

3

4

## Capabilities

5

6

### PBKDF2 (Password-Based Key Derivation Function 2)

7

8

Derives cryptographic keys from passwords using iterative hashing for brute-force resistance.

9

10

```typescript { .api }

11

/**

12

* PBKDF2 key derivation parameters

13

*/

14

interface Pbkdf2Params extends Algorithm {

15

name: "PBKDF2";

16

salt: BufferSource; // Random salt (minimum 64 bits recommended)

17

iterations: number; // Iteration count (minimum 10,000 recommended)

18

hash: "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512"; // Hash algorithm

19

}

20

```

21

22

**Usage Example:**

23

24

```typescript

25

// Import password as key material

26

const password = new TextEncoder().encode("user-password");

27

const passwordKey = await crypto.subtle.importKey(

28

"raw",

29

password,

30

{ name: "PBKDF2" },

31

false,

32

["deriveKey", "deriveBits"]

33

);

34

35

// Generate random salt

36

const salt = crypto.getRandomValues(new Uint8Array(16));

37

38

// Derive AES key from password

39

const derivedKey = await crypto.subtle.deriveKey(

40

{

41

name: "PBKDF2",

42

salt: salt,

43

iterations: 100000,

44

hash: "SHA-256"

45

},

46

passwordKey,

47

{ name: "AES-GCM", length: 256 },

48

false,

49

["encrypt", "decrypt"]

50

);

51

52

// Alternative: derive raw bits

53

const derivedBits = await crypto.subtle.deriveBits(

54

{

55

name: "PBKDF2",

56

salt: salt,

57

iterations: 100000,

58

hash: "SHA-256"

59

},

60

passwordKey,

61

256 // 256 bits output

62

);

63

```

64

65

### HKDF (HMAC-based Key Derivation Function)

66

67

Extracts and expands key material using HMAC for key agreement and key stretching.

68

69

```typescript { .api }

70

/**

71

* HKDF key derivation parameters

72

*/

73

interface HkdfParams extends Algorithm {

74

name: "HKDF";

75

hash: "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512"; // Hash algorithm

76

salt: BufferSource; // Salt value (can be empty)

77

info: BufferSource; // Application-specific context information

78

}

79

```

80

81

**Usage Example:**

82

83

```typescript

84

// Import shared secret as key material

85

const sharedSecret = crypto.getRandomValues(new Uint8Array(32));

86

const baseKey = await crypto.subtle.importKey(

87

"raw",

88

sharedSecret,

89

{ name: "HKDF" },

90

false,

91

["deriveKey", "deriveBits"]

92

);

93

94

// Derive multiple keys from shared secret

95

const salt = new TextEncoder().encode("unique-salt");

96

const info = new TextEncoder().encode("application-context");

97

98

// Derive encryption key

99

const encryptionKey = await crypto.subtle.deriveKey(

100

{

101

name: "HKDF",

102

hash: "SHA-256",

103

salt: salt,

104

info: new TextEncoder().encode("encryption-key")

105

},

106

baseKey,

107

{ name: "AES-GCM", length: 256 },

108

false,

109

["encrypt", "decrypt"]

110

);

111

112

// Derive MAC key

113

const macKey = await crypto.subtle.deriveKey(

114

{

115

name: "HKDF",

116

hash: "SHA-256",

117

salt: salt,

118

info: new TextEncoder().encode("mac-key")

119

},

120

baseKey,

121

{ name: "HMAC", hash: "SHA-256" },

122

false,

123

["sign", "verify"]

124

);

125

```

126

127

### HMAC (Hash-based Message Authentication Code)

128

129

Provides message authentication and integrity verification using cryptographic hash functions.

130

131

```typescript { .api }

132

/**

133

* HMAC key generation parameters

134

*/

135

interface HmacKeyGenParams extends Algorithm {

136

name: "HMAC";

137

hash: "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512";

138

length?: number; // Key length in bits (optional)

139

}

140

141

/**

142

* HMAC operation parameters

143

*/

144

interface HmacParams extends Algorithm {

145

name: "HMAC";

146

}

147

```

148

149

**Usage Example:**

150

151

```typescript

152

// Generate HMAC key

153

const hmacKey = await crypto.subtle.generateKey(

154

{ name: "HMAC", hash: "SHA-256", length: 256 },

155

true,

156

["sign", "verify"]

157

);

158

159

// Create HMAC signature

160

const data = new TextEncoder().encode("Message to authenticate");

161

const signature = await crypto.subtle.sign(

162

{ name: "HMAC" },

163

hmacKey,

164

data

165

);

166

167

// Verify HMAC signature

168

const isValid = await crypto.subtle.verify(

169

{ name: "HMAC" },

170

hmacKey,

171

signature,

172

data

173

);

174

175

// Import HMAC key from raw bytes

176

const keyMaterial = crypto.getRandomValues(new Uint8Array(32));

177

const importedKey = await crypto.subtle.importKey(

178

"raw",

179

keyMaterial,

180

{ name: "HMAC", hash: "SHA-256" },

181

false,

182

["sign", "verify"]

183

);

184

```

185

186

## Key Classes

187

188

### PBKDF2 Key Class

189

190

```typescript { .api }

191

/**

192

* PBKDF2 key for deriving other keys from passwords

193

*/

194

class PbkdfCryptoKey extends SymmetricKey {

195

public algorithm: PbkdfKeyAlgorithm;

196

public type: "secret";

197

public usages: ("deriveKey" | "deriveBits")[];

198

public extractable: boolean;

199

}

200

201

interface PbkdfKeyAlgorithm extends KeyAlgorithm {

202

name: "PBKDF2";

203

}

204

```

205

206

### HKDF Key Class

207

208

```typescript { .api }

209

/**

210

* HKDF key for expanding key material

211

*/

212

class HkdfCryptoKey extends SymmetricKey {

213

public algorithm: HkdfKeyAlgorithm;

214

public type: "secret";

215

public usages: ("deriveKey" | "deriveBits")[];

216

public extractable: boolean;

217

}

218

219

interface HkdfKeyAlgorithm extends KeyAlgorithm {

220

name: "HKDF";

221

}

222

```

223

224

### HMAC Key Class

225

226

```typescript { .api }

227

/**

228

* HMAC key for message authentication

229

*/

230

class HmacCryptoKey extends SymmetricKey {

231

public algorithm: HmacKeyAlgorithm;

232

public type: "secret";

233

public usages: ("sign" | "verify")[];

234

public extractable: boolean;

235

}

236

237

interface HmacKeyAlgorithm extends KeyAlgorithm {

238

name: "HMAC";

239

hash: KeyAlgorithm;

240

length: number;

241

}

242

```

243

244

## Advanced Usage Patterns

245

246

### Key Stretching with PBKDF2

247

248

```typescript

249

async function stretchPassword(

250

password: string,

251

salt: Uint8Array,

252

iterations: number = 100000

253

) {

254

const passwordKey = await crypto.subtle.importKey(

255

"raw",

256

new TextEncoder().encode(password),

257

{ name: "PBKDF2" },

258

false,

259

["deriveBits"]

260

);

261

262

return await crypto.subtle.deriveBits(

263

{

264

name: "PBKDF2",

265

salt: salt,

266

iterations: iterations,

267

hash: "SHA-256"

268

},

269

passwordKey,

270

256

271

);

272

}

273

```

274

275

### Key Expansion with HKDF

276

277

```typescript

278

async function expandKey(

279

masterKey: ArrayBuffer,

280

salt: string,

281

info: string,

282

keyLength: number = 256

283

) {

284

const baseKey = await crypto.subtle.importKey(

285

"raw",

286

masterKey,

287

{ name: "HKDF" },

288

false,

289

["deriveBits"]

290

);

291

292

return await crypto.subtle.deriveBits(

293

{

294

name: "HKDF",

295

hash: "SHA-256",

296

salt: new TextEncoder().encode(salt),

297

info: new TextEncoder().encode(info)

298

},

299

baseKey,

300

keyLength

301

);

302

}

303

```

304

305

### HMAC Chain for Sequential Authentication

306

307

```typescript

308

async function createHmacChain(

309

key: CryptoKey,

310

messages: string[]

311

): Promise<ArrayBuffer[]> {

312

const signatures: ArrayBuffer[] = [];

313

314

for (const message of messages) {

315

const data = new TextEncoder().encode(message);

316

const signature = await crypto.subtle.sign(

317

{ name: "HMAC" },

318

key,

319

data

320

);

321

signatures.push(signature);

322

}

323

324

return signatures;

325

}

326

```

327

328

## Security Best Practices

329

330

### PBKDF2 Recommendations

331

- **Minimum iterations**: 100,000 for SHA-256 (2023 recommendations)

332

- **Salt length**: At least 128 bits (16 bytes) of random data

333

- **Unique salts**: Use different salt for each password

334

- **Hash algorithm**: SHA-256 or stronger

335

336

### HKDF Recommendations

337

- **Salt usage**: Use random salt when possible, empty salt is acceptable

338

- **Info parameter**: Include application context to prevent key reuse

339

- **Hash algorithm**: SHA-256 or stronger for most applications

340

341

### HMAC Recommendations

342

- **Key length**: At least as long as hash output (256 bits for SHA-256)

343

- **Key generation**: Use cryptographically secure random generation

344

- **Hash algorithm**: SHA-256 or stronger, avoid SHA-1

345

346

## Error Handling

347

348

```typescript

349

async function safeDeriveKey(

350

algorithm: any,

351

baseKey: CryptoKey,

352

derivedKeyType: any,

353

extractable: boolean,

354

keyUsages: KeyUsage[]

355

) {

356

try {

357

return await crypto.subtle.deriveKey(

358

algorithm,

359

baseKey,

360

derivedKeyType,

361

extractable,

362

keyUsages

363

);

364

} catch (error) {

365

if (error.name === "InvalidAccessError") {

366

throw new Error("Base key doesn't support key derivation");

367

}

368

if (error.name === "NotSupportedError") {

369

throw new Error("Key derivation algorithm not supported");

370

}

371

if (error.name === "OperationError") {

372

throw new Error("Key derivation failed - check parameters");

373

}

374

throw error;

375

}

376

}

377

```

378

379

## Performance Considerations

380

381

- **PBKDF2**: Higher iteration counts increase security but reduce performance

382

- **HKDF**: Fast operation, suitable for real-time key derivation

383

- **HMAC**: Very fast, suitable for high-throughput authentication

384

- **Caching**: Consider caching derived keys when appropriate for performance