0
# Cryptography & Encoding
1
2
Cryptographic operations, encoding/decoding utilities, and secure random generation for the Ktor framework. Provides thread-safe implementations of common cryptographic operations including hashing, encoding, and nonce generation.
3
4
## Capabilities
5
6
### Base64 Encoding
7
8
Encode and decode data using Base64 format with support for strings, byte arrays, and I/O sources.
9
10
```kotlin { .api }
11
/**
12
* Encode String in base64 format using UTF-8 character encoding
13
* @return Base64 encoded string
14
*/
15
fun String.encodeBase64(): String
16
17
/**
18
* Encode ByteArray in base64 format
19
* @return Base64 encoded string
20
*/
21
fun ByteArray.encodeBase64(): String
22
23
/**
24
* Encode Source (I/O stream) in base64 format
25
* @return Base64 encoded string
26
*/
27
fun Source.encodeBase64(): String
28
```
29
30
**Usage Examples:**
31
32
```kotlin
33
import io.ktor.util.*
34
35
// Encode strings
36
val text = "Hello, World!"
37
val encoded = text.encodeBase64()
38
println(encoded) // "SGVsbG8sIFdvcmxkIQ=="
39
40
// Encode byte arrays
41
val bytes = byteArrayOf(1, 2, 3, 4, 5)
42
val encodedBytes = bytes.encodeBase64()
43
44
// Encode from I/O source
45
val source = buildPacket { writeText("Data to encode") }
46
val encodedSource = source.encodeBase64()
47
```
48
49
### Base64 Decoding
50
51
Decode Base64 encoded data back to original format.
52
53
```kotlin { .api }
54
/**
55
* Decode String from base64 format to UTF-8 string
56
* @return Decoded UTF-8 string
57
*/
58
fun String.decodeBase64String(): String
59
60
/**
61
* Decode String from base64 format to ByteArray
62
* @return Decoded byte array
63
*/
64
fun String.decodeBase64Bytes(): ByteArray
65
66
/**
67
* Decode Source from base64 format
68
* @return Input source with decoded data
69
*/
70
fun Source.decodeBase64Bytes(): Input
71
```
72
73
**Usage Examples:**
74
75
```kotlin
76
import io.ktor.util.*
77
78
// Decode to string
79
val encoded = "SGVsbG8sIFdvcmxkIQ=="
80
val decoded = encoded.decodeBase64String()
81
println(decoded) // "Hello, World!"
82
83
// Decode to bytes
84
val decodedBytes = encoded.decodeBase64Bytes()
85
86
// Decode from source
87
val encodedSource = buildPacket { writeText(encoded) }
88
val decodedInput = encodedSource.decodeBase64Bytes()
89
```
90
91
### Hexadecimal Encoding
92
93
Encode and decode data using hexadecimal format.
94
95
```kotlin { .api }
96
/**
97
* Encode bytes as a HEX string with no spaces, newlines or 0x prefixes
98
* @param bytes Byte array to encode
99
* @return Hexadecimal string representation
100
*/
101
fun hex(bytes: ByteArray): String
102
103
/**
104
* Decode bytes from HEX string (no spaces or 0x prefixes)
105
* @param s Hexadecimal string to decode
106
* @return Decoded byte array
107
*/
108
fun hex(s: String): ByteArray
109
```
110
111
**Usage Examples:**
112
113
```kotlin
114
import io.ktor.util.*
115
116
// Encode bytes to hex
117
val data = "Hello".toByteArray()
118
val hexString = hex(data)
119
println(hexString) // "48656c6c6f"
120
121
// Decode hex string to bytes
122
val decoded = hex("48656c6c6f")
123
val text = String(decoded)
124
println(text) // "Hello"
125
```
126
127
### Hash Functions
128
129
Cryptographic hash function implementations including SHA-1 and stateful digest operations.
130
131
```kotlin { .api }
132
/**
133
* Calculate SHA1 hash of byte array
134
* @param bytes Input data to hash
135
* @return SHA1 hash as byte array
136
*/
137
fun sha1(bytes: ByteArray): ByteArray
138
139
/**
140
* Create Digest from specified hash name (expect/actual function)
141
* @param name Hash algorithm name (e.g., "SHA-1", "SHA-256")
142
* @return Digest instance for stateful hash calculation
143
*/
144
fun Digest(name: String): Digest
145
146
/**
147
* Stateful digest interface for calculating hash values incrementally
148
*/
149
interface Digest {
150
/** Add bytes to digest value */
151
operator fun plusAssign(bytes: ByteArray)
152
153
/** Reset digest state */
154
fun reset()
155
156
/** Calculate digest bytes from current state */
157
suspend fun build(): ByteArray
158
}
159
```
160
161
**Usage Examples:**
162
163
```kotlin
164
import io.ktor.util.*
165
166
// Calculate SHA1 hash
167
val data = "Hello, World!".toByteArray()
168
val hash = sha1(data)
169
val hashHex = hex(hash)
170
println(hashHex) // SHA1 hash in hexadecimal
171
172
// Use stateful digest for incremental hashing
173
val digest = Digest("SHA-1")
174
digest += "Hello, ".toByteArray()
175
digest += "World!".toByteArray()
176
val incrementalHash = digest.build()
177
val incrementalHex = hex(incrementalHash)
178
179
// Reset and reuse digest
180
digest.reset()
181
digest += "New data".toByteArray()
182
val newHash = digest.build()
183
```
184
185
### Nonce Generation
186
187
Generate cryptographically secure random values for security purposes.
188
189
```kotlin { .api }
190
/**
191
* Generate cryptographically secure random nonce
192
* @return Random nonce string
193
*/
194
fun generateNonce(): String
195
196
/**
197
* Generates a nonce bytes of specified size
198
* @param size Number of bytes for the nonce
199
* @return ByteArray containing random nonce data
200
*/
201
fun generateNonce(size: Int): ByteArray
202
203
/**
204
* Interface for nonce management
205
*/
206
interface NonceManager {
207
/** Generate a new nonce */
208
suspend fun newNonce(): String
209
210
/** Verify if a nonce is valid */
211
suspend fun verifyNonce(nonce: String): Boolean
212
}
213
214
/**
215
* Simple nonce manager for testing that generates nonces but accepts all as valid
216
*/
217
object GenerateOnlyNonceManager : NonceManager
218
```
219
220
**Usage Examples:**
221
222
```kotlin
223
import io.ktor.util.*
224
225
// Generate simple nonce
226
val nonce = generateNonce()
227
println("Generated nonce: $nonce")
228
229
// Generate nonce with specific size
230
val nonceBytes = generateNonce(32) // 32 bytes
231
val customNonce = hex(nonceBytes)
232
233
// Use built-in generate-only nonce manager (for testing)
234
val testNonce = GenerateOnlyNonceManager.newNonce()
235
val isValid = GenerateOnlyNonceManager.verifyNonce("any-nonce") // Always returns true
236
237
// Use nonce manager for advanced scenarios
238
class SimpleNonceManager : NonceManager {
239
private val usedNonces = mutableSetOf<String>()
240
241
override suspend fun newNonce(): String {
242
val nonce = generateNonce()
243
usedNonces.add(nonce)
244
return nonce
245
}
246
247
override suspend fun verifyNonce(nonce: String): Boolean {
248
return nonce in usedNonces
249
}
250
}
251
```
252
253
### JVM-Specific Cryptography
254
255
Additional cryptographic utilities available on the JVM platform.
256
257
```kotlin { .api }
258
/**
259
* Stateless nonce manager implementation with HMAC verification and timeout.
260
* Every nonce provided by this manager consists of a random part, timestamp and HMAC.
261
*/
262
class StatelessHmacNonceManager(
263
val keySpec: SecretKeySpec,
264
val algorithm: String = "HmacSHA256",
265
val timeoutMillis: Long = 60000,
266
val nonceGenerator: () -> String = { generateNonce() }
267
) : NonceManager {
268
269
/** Helper constructor that makes a secret key from ByteArray */
270
constructor(
271
key: ByteArray,
272
algorithm: String = "HmacSHA256",
273
timeoutMillis: Long = 60000,
274
nonceGenerator: () -> String = { generateNonce() }
275
)
276
277
override suspend fun newNonce(): String
278
override suspend fun verifyNonce(nonce: String): Boolean
279
}
280
```
281
282
**Usage Examples:**
283
284
```kotlin
285
import io.ktor.util.*
286
import javax.crypto.spec.SecretKeySpec
287
288
// Use HMAC-based nonce manager with ByteArray key
289
val secretKey = "my-secret-key".toByteArray()
290
val nonceManager = StatelessHmacNonceManager(
291
key = secretKey,
292
timeoutMillis = 300_000 // 5 minutes
293
)
294
295
// Generate and verify nonces
296
val nonce = nonceManager.newNonce()
297
val isValid = nonceManager.verifyNonce(nonce) // true within timeout
298
299
// Use with explicit SecretKeySpec
300
val keySpec = SecretKeySpec(secretKey, "HmacSHA256")
301
val advancedManager = StatelessHmacNonceManager(
302
keySpec = keySpec,
303
algorithm = "HmacSHA256",
304
timeoutMillis = 60000
305
)
306
```
307
308
## Implementation Notes
309
310
- **Platform Support**: Base64, hex, and basic crypto functions are available on all platforms (Common)
311
- **JVM Specifics**: StatelessHmacNonceManager and advanced nonce generation features are JVM-only
312
- **Internal Constants**: The library uses an internal constant `NONCE_SIZE_IN_BYTES = 16` for default nonce sizing, but this is not part of the public API