or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

big-number-arithmetic.mdbit-array-utilities.mdcipher-modes.mddata-encoding.mdelliptic-curve-cryptography.mdhash-functions.mdhigh-level-encryption.mdindex.mdkey-derivation.mdkey-exchange.mdmessage-authentication.mdrandom-number-generation.mdsymmetric-encryption.md

key-exchange.mddocs/

0

# Key Exchange

1

2

SJCL provides Secure Remote Password (SRP) protocol implementation for password-authenticated key agreement, allowing secure authentication and key derivation without transmitting passwords over the network.

3

4

## Capabilities

5

6

### SRP (Secure Remote Password)

7

8

The Secure Remote Password protocol allows two parties to authenticate each other and derive a shared secret using only a password, without ever transmitting the password itself.

9

10

```javascript { .api }

11

/**

12

* Calculate SRP verifier for user registration

13

* @param {string} I - Username/identity

14

* @param {string} P - Password

15

* @param {BitArray} s - Salt (random value)

16

* @param {Object} [group] - SRP group parameters (default: SRP-6a with 1024-bit prime)

17

* @returns {BitArray} SRP verifier value

18

*/

19

sjcl.keyexchange.srp.makeVerifier(I, P, s, group);

20

21

/**

22

* Calculate SRP x value (private key derived from password)

23

* @param {string} I - Username/identity

24

* @param {string} P - Password

25

* @param {BitArray} s - Salt value

26

* @returns {BitArray} SRP x value (private key)

27

*/

28

sjcl.keyexchange.srp.makeX(I, P, s);

29

```

30

31

**Usage Examples:**

32

33

```javascript

34

const sjcl = require('sjcl');

35

36

// User registration phase

37

function registerUser(username, password) {

38

// Generate random salt

39

const salt = sjcl.random.randomWords(4); // 128-bit salt

40

41

// Calculate verifier for storage on server

42

const verifier = sjcl.keyexchange.srp.makeVerifier(username, password, salt);

43

44

// Store username, salt, and verifier on server

45

// NEVER store the actual password

46

return {

47

username: username,

48

salt: salt,

49

verifier: verifier

50

};

51

}

52

53

// Example registration

54

const userRecord = registerUser("alice@example.com", "strongPassword123");

55

console.log("User registered with salt:", sjcl.codec.hex.fromBits(userRecord.salt));

56

console.log("Verifier:", sjcl.codec.hex.fromBits(userRecord.verifier));

57

58

// Calculate x value (used internally during authentication)

59

const xValue = sjcl.keyexchange.srp.makeX("alice@example.com", "strongPassword123", userRecord.salt);

60

console.log("X value:", sjcl.codec.hex.fromBits(xValue));

61

```

62

63

## SRP Protocol Overview

64

65

The SRP protocol consists of several phases:

66

67

### 1. Registration Phase

68

69

During user registration, the client calculates a verifier that the server stores instead of the password.

70

71

```javascript

72

const sjcl = require('sjcl');

73

74

function srpRegistration(username, password) {

75

// Client generates salt (or server can generate and send to client)

76

const salt = sjcl.random.randomWords(4);

77

78

// Client calculates verifier

79

const verifier = sjcl.keyexchange.srp.makeVerifier(username, password, salt);

80

81

// Send username, salt, and verifier to server for storage

82

return {

83

username: username,

84

salt: sjcl.codec.hex.fromBits(salt),

85

verifier: sjcl.codec.hex.fromBits(verifier)

86

};

87

}

88

89

// Usage

90

const registration = srpRegistration("user@domain.com", "mySecurePassword");

91

console.log("Registration data:", registration);

92

```

93

94

### 2. Authentication Phase

95

96

During authentication, both client and server perform calculations to verify the password without transmitting it.

97

98

```javascript

99

const sjcl = require('sjcl');

100

101

// Client-side authentication start

102

function clientAuthStart(username, password, saltFromServer) {

103

// Convert salt from hex if received from server

104

const salt = sjcl.codec.hex.toBits(saltFromServer);

105

106

// Calculate x (private key)

107

const x = sjcl.keyexchange.srp.makeX(username, password, salt);

108

109

// In full SRP implementation, client would also:

110

// 1. Generate random 'a' value

111

// 2. Calculate A = g^a mod N (public key)

112

// 3. Send A to server

113

114

return {

115

x: x,

116

// Additional SRP values would be calculated here

117

};

118

}

119

120

// Server-side verification preparation

121

function serverPrepareAuth(storedUserRecord) {

122

// Server has stored: username, salt, verifier

123

// In full SRP implementation, server would:

124

// 1. Generate random 'b' value

125

// 2. Calculate B = (kv + g^b) mod N

126

// 3. Send B and salt to client

127

128

return {

129

salt: storedUserRecord.salt,

130

// B value would be calculated and included

131

};

132

}

133

```

134

135

## SRP Security Properties

136

137

### Key Features

138

139

1. **Password Never Transmitted**: The actual password never goes over the network

140

2. **Zero-Knowledge**: Server learns nothing about the password

141

3. **Mutual Authentication**: Both parties verify each other's identity

142

4. **Forward Secrecy**: Session keys are ephemeral

143

5. **Offline Attack Resistance**: Server compromise doesn't immediately reveal passwords

144

145

### Security Considerations

146

147

```javascript

148

const sjcl = require('sjcl');

149

150

// Best practices for SRP implementation

151

class SRPBestPractices {

152

static generateSecureSalt() {

153

// Use at least 128 bits of random salt

154

return sjcl.random.randomWords(4);

155

}

156

157

static validateUsername(username) {

158

// Normalize username to prevent attacks

159

return username.toLowerCase().trim();

160

}

161

162

static strengthenPassword(password) {

163

// Consider additional password strengthening

164

// This is a simplified example

165

if (password.length < 8) {

166

throw new Error("Password too short");

167

}

168

return password;

169

}

170

171

static secureRegistration(username, password) {

172

const normalizedUsername = SRPBestPractices.validateUsername(username);

173

const strengthenedPassword = SRPBestPractices.strengthenPassword(password);

174

const salt = SRPBestPractices.generateSecureSalt();

175

176

const verifier = sjcl.keyexchange.srp.makeVerifier(

177

normalizedUsername,

178

strengthenedPassword,

179

salt

180

);

181

182

return {

183

username: normalizedUsername,

184

salt: salt,

185

verifier: verifier,

186

timestamp: Date.now()

187

};

188

}

189

}

190

191

// Usage with best practices

192

try {

193

const secureReg = SRPBestPractices.secureRegistration("User@Example.com", "MyStrongPassword123!");

194

console.log("Secure registration successful");

195

} catch (error) {

196

console.error("Registration failed:", error.message);

197

}

198

```

199

200

## Advanced SRP Usage

201

202

### Custom Group Parameters

203

204

SRP can use different mathematical groups for different security levels:

205

206

```javascript

207

const sjcl = require('sjcl');

208

209

// Example of using SRP with custom parameters

210

function srpWithCustomGroup(username, password, salt, customGroup) {

211

// Custom group would define different prime modulus and generator

212

// This is an advanced feature for specific security requirements

213

214

const verifier = sjcl.keyexchange.srp.makeVerifier(

215

username,

216

password,

217

salt,

218

customGroup

219

);

220

221

return verifier;

222

}

223

224

// Note: Custom groups require careful cryptographic analysis

225

// Default parameters are recommended for most applications

226

```

227

228

### SRP with Additional Key Derivation

229

230

Combine SRP with other key derivation methods:

231

232

```javascript

233

const sjcl = require('sjcl');

234

235

function enhancedSRPRegistration(username, password, additionalEntropy) {

236

// Generate salt

237

const salt = sjcl.random.randomWords(4);

238

239

// Optional: Strengthen password with additional entropy

240

const strengthenedPassword = password + additionalEntropy;

241

242

// Calculate SRP verifier

243

const verifier = sjcl.keyexchange.srp.makeVerifier(username, strengthenedPassword, salt);

244

245

// Derive additional keys using HKDF

246

const masterKey = sjcl.misc.hkdf(

247

verifier,

248

256,

249

salt,

250

sjcl.codec.utf8String.toBits("SRP-master-key")

251

);

252

253

const authKey = sjcl.misc.hkdf(

254

masterKey,

255

256,

256

salt,

257

sjcl.codec.utf8String.toBits("authentication")

258

);

259

260

return {

261

username: username,

262

salt: salt,

263

verifier: verifier,

264

authKey: authKey

265

};

266

}

267

268

// Usage

269

const enhancedReg = enhancedSRPRegistration(

270

"user@example.com",

271

"password123",

272

"device-specific-entropy"

273

);

274

```

275

276

## Integration Examples

277

278

### Web Application Integration

279

280

Example of integrating SRP into a web application:

281

282

```javascript

283

const sjcl = require('sjcl');

284

285

class WebSRPClient {

286

constructor(apiEndpoint) {

287

this.apiEndpoint = apiEndpoint;

288

}

289

290

async register(username, password) {

291

// Client-side registration

292

const salt = sjcl.random.randomWords(4);

293

const verifier = sjcl.keyexchange.srp.makeVerifier(username, password, salt);

294

295

// Send to server

296

const registrationData = {

297

username: username,

298

salt: sjcl.codec.hex.fromBits(salt),

299

verifier: sjcl.codec.hex.fromBits(verifier)

300

};

301

302

// In real implementation, this would be an HTTP request

303

console.log("Would send to server:", registrationData);

304

return true;

305

}

306

307

async authenticate(username, password) {

308

// Step 1: Get salt from server

309

// const { salt } = await fetch(`${this.apiEndpoint}/auth/salt/${username}`);

310

311

// Step 2: Calculate client credentials

312

const salt = sjcl.random.randomWords(4); // In real app, from server

313

const x = sjcl.keyexchange.srp.makeX(username, password, salt);

314

315

// Step 3: Continue with full SRP protocol

316

// (Additional steps would involve A/B value exchange)

317

318

console.log("Authentication x value calculated");

319

return { success: true, sessionKey: "derived-session-key" };

320

}

321

}

322

323

// Usage

324

const srpClient = new WebSRPClient("https://api.example.com");

325

// srpClient.register("user@example.com", "securePassword");

326

```

327

328

## Security Recommendations

329

330

1. **Salt Generation**: Always use cryptographically secure random salts (≥128 bits)

331

2. **Password Policy**: Enforce strong password requirements

332

3. **Username Handling**: Normalize usernames consistently

333

4. **Timing Attacks**: Be aware that SRP operations are not constant-time

334

5. **Group Parameters**: Use well-vetted SRP group parameters

335

6. **Protocol Completion**: Implement the full SRP protocol, not just verifier generation

336

7. **Session Management**: Properly manage derived session keys

337

8. **Transport Security**: Always use SRP over secure channels (HTTPS/TLS)

338

339

## Common Use Cases

340

341

1. **Password-Based Authentication**: Secure login without password transmission

342

2. **Zero-Knowledge Proofs**: Prove password knowledge without revealing it

343

3. **Mutual Authentication**: Both client and server authenticate each other

344

4. **Key Agreement**: Derive shared session keys from passwords

345

5. **Enterprise SSO**: Single sign-on systems requiring password verification

346

6. **Secure Messaging**: Authenticate messaging clients without storing passwords

347

348

## Limitations

349

350

1. **Protocol Complexity**: SRP requires careful implementation of the full protocol

351

2. **Performance**: More computationally expensive than simple password hashing

352

3. **Implementation Risk**: Incorrect implementation can compromise security

353

4. **Limited Library Support**: Not all platforms have mature SRP implementations

354

5. **User Experience**: May require additional steps compared to traditional authentication