or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

buffer.mdbytestring.mdfilesystem.mdhashing.mdindex.mdjvm-extensions.mdsources-sinks.md

hashing.mddocs/

0

# Hash and Cryptographic Operations

1

2

Okio provides built-in hashing and cryptographic operations for data integrity and security. These operations can be performed on ByteString, Buffer, and streaming data through Sources and Sinks.

3

4

## Capabilities

5

6

### ByteString Hashing

7

8

Compute hashes directly on ByteString instances.

9

10

```kotlin { .api }

11

/**

12

* Computes MD5 hash of ByteString content (deprecated)

13

* @return ByteString containing MD5 hash (16 bytes)

14

*/

15

abstract fun ByteString.md5(): ByteString

16

17

/**

18

* Computes SHA-1 hash of ByteString content (deprecated)

19

* @return ByteString containing SHA-1 hash (20 bytes)

20

*/

21

abstract fun ByteString.sha1(): ByteString

22

23

/**

24

* Computes SHA-256 hash of ByteString content

25

* @return ByteString containing SHA-256 hash (32 bytes)

26

*/

27

abstract fun ByteString.sha256(): ByteString

28

29

/**

30

* Computes SHA-512 hash of ByteString content

31

* @return ByteString containing SHA-512 hash (64 bytes)

32

*/

33

abstract fun ByteString.sha512(): ByteString

34

35

/**

36

* Computes HMAC-SHA1 with the given key (deprecated)

37

* @param key Secret key for HMAC computation

38

* @return ByteString containing HMAC-SHA1 (20 bytes)

39

*/

40

@Deprecated("Use hmacSha256 instead", ReplaceWith("hmacSha256(key)"))

41

abstract fun ByteString.hmacSha1(key: ByteString): ByteString

42

43

/**

44

* Computes HMAC-SHA256 with the given key

45

* @param key Secret key for HMAC computation

46

* @return ByteString containing HMAC-SHA256 (32 bytes)

47

*/

48

abstract fun ByteString.hmacSha256(key: ByteString): ByteString

49

50

/**

51

* Computes HMAC-SHA512 with the given key

52

* @param key Secret key for HMAC computation

53

* @return ByteString containing HMAC-SHA512 (64 bytes)

54

*/

55

abstract fun ByteString.hmacSha512(key: ByteString): ByteString

56

```

57

58

**Usage Examples:**

59

60

```kotlin

61

val data = "Hello, World!".encodeUtf8()

62

val key = "secret-key".encodeUtf8()

63

64

// Basic hashing

65

val md5 = data.md5()

66

println("MD5: ${md5.hex()}")

67

68

val sha256 = data.sha256()

69

println("SHA-256: ${sha256.hex()}")

70

71

val sha512 = data.sha512()

72

println("SHA-512: ${sha512.hex()}")

73

74

// HMAC with key

75

val hmac256 = data.hmacSha256(key)

76

println("HMAC-SHA256: ${hmac256.hex()}")

77

78

val hmac512 = data.hmacSha512(key)

79

println("HMAC-SHA512: ${hmac512.hex()}")

80

```

81

82

### Buffer Hashing

83

84

Compute hashes on Buffer content without consuming the data.

85

86

```kotlin { .api }

87

/**

88

* Computes MD5 hash of Buffer content (deprecated)

89

* @return ByteString containing MD5 hash

90

*/

91

fun Buffer.md5(): ByteString

92

93

/**

94

* Computes SHA-1 hash of Buffer content (deprecated)

95

* @return ByteString containing SHA-1 hash

96

*/

97

fun Buffer.sha1(): ByteString

98

99

/**

100

* Computes SHA-256 hash of Buffer content

101

* @return ByteString containing SHA-256 hash

102

*/

103

fun Buffer.sha256(): ByteString

104

105

/**

106

* Computes SHA-512 hash of Buffer content

107

* @return ByteString containing SHA-512 hash

108

*/

109

fun Buffer.sha512(): ByteString

110

111

/**

112

* Computes HMAC-SHA1 of Buffer content (deprecated)

113

* @param key Secret key for HMAC computation

114

* @return ByteString containing HMAC-SHA1

115

*/

116

@Deprecated("Use hmacSha256 instead")

117

fun Buffer.hmacSha1(key: ByteString): ByteString

118

119

/**

120

* Computes HMAC-SHA256 of Buffer content

121

* @param key Secret key for HMAC computation

122

* @return ByteString containing HMAC-SHA256

123

*/

124

fun Buffer.hmacSha256(key: ByteString): ByteString

125

126

/**

127

* Computes HMAC-SHA512 of Buffer content

128

* @param key Secret key for HMAC computation

129

* @return ByteString containing HMAC-SHA512

130

*/

131

fun Buffer.hmacSha512(key: ByteString): ByteString

132

```

133

134

**Usage Examples:**

135

136

```kotlin

137

val buffer = Buffer()

138

buffer.writeUtf8("Hello, World!")

139

buffer.writeInt(42)

140

141

// Hash without consuming buffer data

142

val hash = buffer.sha256()

143

println("Buffer SHA-256: ${hash.hex()}")

144

println("Buffer still has ${buffer.size} bytes")

145

146

// HMAC of buffer content

147

val key = "secret".encodeUtf8()

148

val hmac = buffer.hmacSha256(key)

149

println("Buffer HMAC: ${hmac.hex()}")

150

```

151

152

### Streaming Hash Computation

153

154

Compute hashes while reading from Sources or writing to Sinks.

155

156

```kotlin { .api }

157

/**

158

* Sink that computes a hash while writing data

159

* Wraps another sink and computes hash of all data written

160

*/

161

abstract class HashingSink : Sink {

162

/**

163

* Current hash value of all data written so far

164

*/

165

abstract val hash: ByteString

166

167

companion object {

168

/**

169

* Creates a HashingSink that computes MD5 (deprecated)

170

* @param sink Underlying sink to write to

171

* @return HashingSink that computes MD5

172

*/

173

fun md5(sink: Sink): HashingSink

174

175

/**

176

* Creates a HashingSink that computes SHA-1 (deprecated)

177

* @param sink Underlying sink to write to

178

* @return HashingSink that computes SHA-1

179

*/

180

fun sha1(sink: Sink): HashingSink

181

182

/**

183

* Creates a HashingSink that computes SHA-256

184

* @param sink Underlying sink to write to

185

* @return HashingSink that computes SHA-256

186

*/

187

fun sha256(sink: Sink): HashingSink

188

189

/**

190

* Creates a HashingSink that computes SHA-512

191

* @param sink Underlying sink to write to

192

* @return HashingSink that computes SHA-512

193

*/

194

fun sha512(sink: Sink): HashingSink

195

196

/**

197

* Creates a HashingSink that computes HMAC-SHA1 (deprecated)

198

* @param sink Underlying sink to write to

199

* @param key Secret key for HMAC computation

200

* @return HashingSink that computes HMAC-SHA1

201

*/

202

@Deprecated("Use hmacSha256 instead")

203

fun hmacSha1(sink: Sink, key: ByteString): HashingSink

204

205

/**

206

* Creates a HashingSink that computes HMAC-SHA256

207

* @param sink Underlying sink to write to

208

* @param key Secret key for HMAC computation

209

* @return HashingSink that computes HMAC-SHA256

210

*/

211

fun hmacSha256(sink: Sink, key: ByteString): HashingSink

212

213

/**

214

* Creates a HashingSink that computes HMAC-SHA512

215

* @param sink Underlying sink to write to

216

* @param key Secret key for HMAC computation

217

* @return HashingSink that computes HMAC-SHA512

218

*/

219

fun hmacSha512(sink: Sink, key: ByteString): HashingSink

220

}

221

}

222

223

/**

224

* Source that computes a hash while reading data

225

* Wraps another source and computes hash of all data read

226

*/

227

abstract class HashingSource : Source {

228

/**

229

* Current hash value of all data read so far

230

*/

231

abstract val hash: ByteString

232

233

companion object {

234

/**

235

* Creates a HashingSource that computes MD5 (deprecated)

236

* @param source Underlying source to read from

237

* @return HashingSource that computes MD5

238

*/

239

fun md5(source: Source): HashingSource

240

241

/**

242

* Creates a HashingSource that computes SHA-1 (deprecated)

243

* @param source Underlying source to read from

244

* @return HashingSource that computes SHA-1

245

*/

246

fun sha1(source: Source): HashingSource

247

248

/**

249

* Creates a HashingSource that computes SHA-256

250

* @param source Underlying source to read from

251

* @return HashingSource that computes SHA-256

252

*/

253

fun sha256(source: Source): HashingSource

254

255

/**

256

* Creates a HashingSource that computes SHA-512

257

* @param source Underlying source to read from

258

* @return HashingSource that computes SHA-512

259

*/

260

fun sha512(source: Source): HashingSource

261

262

/**

263

* Creates a HashingSource that computes HMAC-SHA1 (deprecated)

264

* @param source Underlying source to read from

265

* @param key Secret key for HMAC computation

266

* @return HashingSource that computes HMAC-SHA1

267

*/

268

@Deprecated("Use hmacSha256 instead")

269

fun hmacSha1(source: Source, key: ByteString): HashingSource

270

271

/**

272

* Creates a HashingSource that computes HMAC-SHA256

273

* @param source Underlying source to read from

274

* @param key Secret key for HMAC computation

275

* @return HashingSource that computes HMAC-SHA256

276

*/

277

fun hmacSha256(source: Source, key: ByteString): HashingSource

278

279

/**

280

* Creates a HashingSource that computes HMAC-SHA512

281

* @param source Underlying source to read from

282

* @param key Secret key for HMAC computation

283

* @return HashingSource that computes HMAC-SHA512

284

*/

285

fun hmacSha512(source: Source, key: ByteString): HashingSource

286

}

287

}

288

```

289

290

**Usage Examples:**

291

292

```kotlin

293

// Hash while writing to file

294

val path = "/tmp/data.txt".toPath()

295

val fileSink = FileSystem.SYSTEM.sink(path)

296

val hashingSink = HashingSink.sha256(fileSink)

297

val bufferedSink = hashingSink.buffer()

298

299

bufferedSink.writeUtf8("Hello, World!")

300

bufferedSink.writeInt(42)

301

bufferedSink.close()

302

303

println("File SHA-256: ${hashingSink.hash.hex()}")

304

305

// Hash while reading from file

306

val fileSource = FileSystem.SYSTEM.source(path)

307

val hashingSource = HashingSource.sha256(fileSource)

308

val bufferedSource = hashingSource.buffer()

309

310

val content = bufferedSource.readUtf8()

311

val number = bufferedSource.readInt()

312

bufferedSource.close()

313

314

println("Content: $content, Number: $number")

315

println("Read SHA-256: ${hashingSource.hash.hex()}")

316

317

// HMAC while streaming

318

val key = "secret-key".encodeUtf8()

319

val hmacSink = HashingSink.hmacSha256(blackholeSink(), key)

320

val buffer = Buffer()

321

322

hmacSink.write(buffer.writeUtf8("Streaming data"), 13)

323

hmacSink.flush()

324

println("Streaming HMAC: ${hmacSink.hash.hex()}")

325

```

326

327

### Hash Verification

328

329

Common patterns for verifying data integrity.

330

331

```kotlin { .api }

332

/**

333

* Verifies data integrity by comparing computed hash with expected hash

334

* @param expectedHash Expected hash value

335

* @param actualHash Computed hash value

336

* @return true if hashes match

337

*/

338

fun verifyHash(expectedHash: ByteString, actualHash: ByteString): Boolean =

339

expectedHash == actualHash

340

341

/**

342

* Verifies data integrity by comparing hex-encoded hashes

343

* @param expectedHex Expected hash as hex string

344

* @param actualHash Computed hash value

345

* @return true if hashes match

346

*/

347

fun verifyHashHex(expectedHex: String, actualHash: ByteString): Boolean =

348

expectedHex.lowercase() == actualHash.hex()

349

```

350

351

**Usage Examples:**

352

353

```kotlin

354

// Download and verify file integrity

355

val expectedSha256 = "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"

356

val downloadedData = "hello".encodeUtf8()

357

358

val actualHash = downloadedData.sha256()

359

val isValid = verifyHashHex(expectedSha256, actualHash)

360

println("File integrity: ${if (isValid) "VALID" else "INVALID"}")

361

362

// Verify HMAC for authentication

363

val message = "authenticated message".encodeUtf8()

364

val sharedKey = "shared-secret".encodeUtf8()

365

val computedHmac = message.hmacSha256(sharedKey)

366

367

// Later, verify the message

368

val receivedMessage = "authenticated message".encodeUtf8()

369

val receivedHmac = computedHmac // would come from sender

370

val verificationHmac = receivedMessage.hmacSha256(sharedKey)

371

val isAuthentic = verifyHash(receivedHmac, verificationHmac)

372

println("Message authentic: ${if (isAuthentic) "YES" else "NO"}")

373

374

// Stream large file and verify hash

375

val largeFile = "/tmp/large-file.dat".toPath()

376

val expectedHash = "expected-hash-value".decodeHex()

377

378

val source = FileSystem.SYSTEM.source(largeFile)

379

val hashingSource = HashingSource.sha256(source)

380

val buffer = Buffer()

381

382

// Read entire file through hashing source

383

while (!hashingSource.exhausted()) {

384

hashingSource.read(buffer, 8192)

385

buffer.clear() // Process data in chunks

386

}

387

hashingSource.close()

388

389

val fileValid = verifyHash(expectedHash, hashingSource.hash)

390

println("Large file integrity: ${if (fileValid) "VALID" else "INVALID"}")

391

```