0
# YubiKey Configuration
1
2
Comprehensive YubiKey configuration system supporting all operational modes including Yubico OTP, OATH-HOTP, and challenge-response with full control over device settings, flags, and security parameters.
3
4
## Capabilities
5
6
### Configuration Object Creation
7
8
Create and initialize YubiKey configuration objects with version compatibility checking.
9
10
```python { .api }
11
class YubiKeyConfig:
12
def __init__(self, ykver=None, capabilities=None, update=False, swap=False, zap=False):
13
"""
14
Initialize YubiKey configuration object.
15
16
Parameters:
17
- ykver (tuple): YubiKey version tuple for compatibility checking
18
- capabilities (YubiKeyCapabilities): Device capabilities object
19
- update (bool): True for configuration update (preserves other slot)
20
- swap (bool): True to swap configuration slots after writing
21
- zap (bool): True to clear configuration slot
22
"""
23
24
def version_required(self):
25
"""
26
Get minimum YubiKey version required for this configuration.
27
28
Returns:
29
tuple: Minimum version tuple (major, minor, build)
30
"""
31
```
32
33
Basic configuration creation:
34
35
```python
36
import yubico
37
from yubico.yubikey_config import YubiKeyConfig
38
39
yk = yubico.find_yubikey()
40
41
# Create new configuration
42
cfg = YubiKeyConfig()
43
44
# Or use device-specific initialization
45
cfg = yk.init_config()
46
47
# Check version requirements
48
min_version = cfg.version_required()
49
print(f"Minimum version required: {min_version}")
50
```
51
52
### Yubico OTP Configuration
53
54
Configure YubiKey for standard Yubico OTP validation with Yubico's authentication servers.
55
56
```python { .api }
57
def mode_yubikey_otp(self, private_uid, aes_key):
58
"""
59
Configure YubiKey for Yubico OTP mode.
60
61
Parameters:
62
- private_uid (bytes): 6-byte private UID
63
- aes_key (bytes): 16-byte AES key
64
65
Raises:
66
InputError: If parameters are invalid
67
"""
68
```
69
70
Yubico OTP configuration example:
71
72
```python
73
import yubico
74
from yubico.yubikey_config import YubiKeyConfig
75
import os
76
77
yk = yubico.find_yubikey()
78
cfg = yk.init_config()
79
80
# Generate random private UID and AES key
81
private_uid = os.urandom(6)
82
aes_key = os.urandom(16)
83
84
# Configure for Yubico OTP
85
cfg.mode_yubikey_otp(private_uid, aes_key)
86
87
# Write to slot 1
88
yk.write_config(cfg, slot=1)
89
print("Yubico OTP configured")
90
```
91
92
### OATH-HOTP Configuration
93
94
Configure YubiKey for OATH-HOTP (RFC 4226) authentication.
95
96
```python { .api }
97
def mode_oath_hotp(self, secret, digits=6, factor_seed=None, omp=0x0, tt=0x0, mui=''):
98
"""
99
Configure YubiKey for OATH-HOTP mode.
100
101
Parameters:
102
- secret (bytes): HOTP secret key (up to 20 bytes)
103
- digits (int): Number of digits in HOTP output (6 or 8)
104
- factor_seed (int): Initial counter value
105
- omp (int): Moving factor seed
106
- tt (int): Truncation offset
107
- mui (str): Management Unit Identifier
108
109
Raises:
110
InputError: If parameters are invalid
111
"""
112
```
113
114
OATH-HOTP configuration example:
115
116
```python
117
import yubico
118
from yubico.yubikey_config import YubiKeyConfig
119
import base32
120
121
yk = yubico.find_yubikey()
122
cfg = yk.init_config()
123
124
# Use standard base32-encoded secret
125
secret_b32 = "JBSWY3DPEHPK3PXP"
126
secret = base32.b32decode(secret_b32)
127
128
# Configure for OATH-HOTP with 6 digits
129
cfg.mode_oath_hotp(secret, digits=6, factor_seed=1)
130
131
# Write to slot 2
132
yk.write_config(cfg, slot=2)
133
print("OATH-HOTP configured")
134
```
135
136
### Challenge-Response Configuration
137
138
Configure YubiKey for challenge-response authentication using HMAC-SHA1 or Yubico protocols.
139
140
```python { .api }
141
def mode_challenge_response(self, secret, type='HMAC', variable=True, require_button=False):
142
"""
143
Configure YubiKey for challenge-response mode.
144
145
Parameters:
146
- secret (bytes): Secret key (up to 20 bytes for HMAC, 16 bytes for Yubico)
147
- type (str): Challenge type - 'HMAC' for HMAC-SHA1 or 'OTP' for Yubico
148
- variable (bool): Variable length response (HMAC only)
149
- require_button (bool): Require button press for challenge-response
150
151
Raises:
152
InputError: If parameters are invalid
153
"""
154
```
155
156
Challenge-response configuration example:
157
158
```python
159
import yubico
160
from yubico.yubikey_config import YubiKeyConfig
161
import os
162
163
yk = yubico.find_yubikey()
164
cfg = yk.init_config()
165
166
# Generate random secret for HMAC-SHA1
167
secret = os.urandom(20)
168
169
# Configure for HMAC challenge-response
170
cfg.mode_challenge_response(
171
secret=secret,
172
type='HMAC',
173
variable=True,
174
require_button=False
175
)
176
177
# Write to slot 1
178
yk.write_config(cfg, slot=1)
179
print("Challenge-response configured")
180
181
# Test the configuration
182
challenge = b"test challenge"
183
response = yk.challenge_response(challenge, slot=1)
184
print(f"Response: {response.hex()}")
185
```
186
187
### Cryptographic Key Management
188
189
Set various cryptographic keys and access codes for YubiKey security.
190
191
```python { .api }
192
def aes_key(self, data):
193
"""
194
Set AES128 key for YubiKey operations.
195
196
Parameters:
197
- data (bytes): 16-byte AES key
198
199
Raises:
200
InputError: If key length is invalid
201
"""
202
203
def unlock_key(self, data):
204
"""
205
Set access code required for re-programming this configuration.
206
207
Parameters:
208
- data (bytes): 6-byte access code
209
"""
210
211
def access_key(self, data):
212
"""
213
Set new access code for future programming operations.
214
215
Parameters:
216
- data (bytes): 6-byte access code
217
"""
218
```
219
220
Key management example:
221
222
```python
223
import yubico
224
from yubico.yubikey_config import YubiKeyConfig
225
import os
226
227
yk = yubico.find_yubikey()
228
cfg = yk.init_config()
229
230
# Set AES key
231
aes_key = os.urandom(16)
232
cfg.aes_key(aes_key)
233
234
# Set access code for future programming
235
access_code = os.urandom(6)
236
cfg.access_key(access_code)
237
238
# Configure mode and write
239
cfg.mode_yubikey_otp(os.urandom(6), aes_key)
240
yk.write_config(cfg, slot=1)
241
```
242
243
### Configuration Flags
244
245
Control YubiKey behavior through various configuration flags.
246
247
```python { .api }
248
def ticket_flag(self, which, new=None):
249
"""
250
Get or set ticket flags.
251
252
Parameters:
253
- which (str): Flag name (e.g., 'APPEND_CR', 'APPEND_TAB')
254
- new (bool): New flag value, or None to query current value
255
256
Returns:
257
bool: Current flag value if new is None
258
"""
259
260
def config_flag(self, which, new=None):
261
"""
262
Get or set configuration flags.
263
264
Parameters:
265
- which (str): Flag name (e.g., 'SEND_REF', 'TICKET_FIRST')
266
- new (bool): New flag value, or None to query current value
267
268
Returns:
269
bool: Current flag value if new is None
270
"""
271
272
def extended_flag(self, which, new=None):
273
"""
274
Get or set extended flags.
275
276
Parameters:
277
- which (str): Flag name (e.g., 'SERIAL_BTN_VISIBLE', 'SERIAL_USB_VISIBLE')
278
- new (bool): New flag value, or None to query current value
279
280
Returns:
281
bool: Current flag value if new is None
282
"""
283
```
284
285
Configuration flags example:
286
287
```python
288
import yubico
289
from yubico.yubikey_config import YubiKeyConfig
290
291
yk = yubico.find_yubikey()
292
cfg = yk.init_config()
293
294
# Set ticket flags
295
cfg.ticket_flag('APPEND_CR', True) # Append carriage return
296
cfg.ticket_flag('APPEND_TAB', False) # Don't append tab
297
298
# Set configuration flags
299
cfg.config_flag('SEND_REF', True) # Send reference string first
300
cfg.config_flag('TICKET_FIRST', False)
301
302
# Set extended flags
303
cfg.extended_flag('SERIAL_BTN_VISIBLE', True) # Serial visible after button press
304
cfg.extended_flag('SERIAL_USB_VISIBLE', False) # Serial not visible via USB
305
306
# Query current flag values
307
cr_flag = cfg.ticket_flag('APPEND_CR')
308
print(f"APPEND_CR flag: {cr_flag}")
309
```
310
311
### Token Identifier Configuration
312
313
Configure the fixed string (Token Identifier) portion of YubiKey output.
314
315
```python { .api }
316
def fixed_string(self, data=None):
317
"""
318
Get or set fixed string (Token Identifier).
319
320
The fixed string is the first part of YubiKey OTP output and can be
321
used to identify the specific YubiKey or user.
322
323
Parameters:
324
- data (bytes): Fixed string data (up to 16 bytes), or None to query
325
326
Returns:
327
bytes: Current fixed string if data is None
328
"""
329
```
330
331
Fixed string configuration example:
332
333
```python
334
import yubico
335
from yubico.yubikey_config import YubiKeyConfig
336
337
yk = yubico.find_yubikey()
338
cfg = yk.init_config()
339
340
# Set custom fixed string (Token Identifier)
341
token_id = b"mytoken001"
342
cfg.fixed_string(token_id)
343
344
# Configure Yubico OTP mode
345
cfg.mode_yubikey_otp(os.urandom(6), os.urandom(16))
346
347
# Write configuration
348
yk.write_config(cfg, slot=1)
349
print(f"Token ID set to: {token_id}")
350
```
351
352
### Advanced Configuration Options
353
354
Enable advanced YubiKey features and modes.
355
356
```python { .api }
357
def enable_extended_scan_code_mode(self):
358
"""
359
Enable extended scan code mode.
360
361
Allows YubiKey to output characters not available in basic scan code mode.
362
"""
363
364
def enable_shifted_1(self):
365
"""
366
Enable shifted character 1 before output.
367
368
Prepends shifted character 1 to YubiKey output.
369
"""
370
```
371
372
Advanced configuration example:
373
374
```python
375
import yubico
376
from yubico.yubikey_config import YubiKeyConfig
377
378
yk = yubico.find_yubikey()
379
cfg = yk.init_config()
380
381
# Enable advanced features
382
cfg.enable_extended_scan_code_mode()
383
cfg.enable_shifted_1()
384
385
# Configure and write
386
cfg.mode_yubikey_otp(os.urandom(6), os.urandom(16))
387
yk.write_config(cfg, slot=1)
388
```
389
390
### Configuration Export
391
392
Export configuration objects as binary data or frames for transmission.
393
394
```python { .api }
395
def to_string(self):
396
"""
397
Export configuration as 64-byte binary string.
398
399
Returns:
400
bytes: 64-byte configuration data
401
"""
402
403
def to_frame(self, slot=1):
404
"""
405
Export configuration as YubiKeyFrame object.
406
407
Parameters:
408
- slot (int): Target configuration slot
409
410
Returns:
411
YubiKeyFrame: Frame object ready for transmission
412
"""
413
```
414
415
Configuration export example:
416
417
```python
418
import yubico
419
from yubico.yubikey_config import YubiKeyConfig
420
421
yk = yubico.find_yubikey()
422
cfg = yk.init_config()
423
424
# Configure YubiKey
425
cfg.mode_challenge_response(os.urandom(20))
426
427
# Export as binary data
428
config_data = cfg.to_string()
429
print(f"Configuration size: {len(config_data)} bytes")
430
431
# Export as frame
432
frame = cfg.to_frame(slot=1)
433
print(f"Frame command: {frame.command}")
434
```
435
436
## Configuration Validation
437
438
The configuration system includes automatic validation and version compatibility checking:
439
440
```python
441
import yubico
442
from yubico.yubikey_config import YubiKeyConfig, YubiKeyConfigError
443
444
try:
445
yk = yubico.find_yubikey()
446
cfg = yk.init_config()
447
448
# Invalid configuration will raise error
449
cfg.mode_oath_hotp(b"too_long_secret_key_data", digits=10) # Invalid
450
451
except YubiKeyConfigError as e:
452
print(f"Configuration error: {e.reason}")
453
except yubico.yubikey_base.YubiKeyVersionError as e:
454
print(f"Version compatibility error: {e.reason}")
455
```