0
# HOTP Devices
1
2
HMAC-based one-time passwords (HOTP) following RFC 4226, using a counter that increments with each successful verification. HOTP devices are useful when time synchronization is not reliable.
3
4
## Capabilities
5
6
### HOTPDevice Model
7
8
```python { .api }
9
class HOTPDevice(TimestampMixin, ThrottlingMixin, Device):
10
"""
11
HMAC-based OTP device following RFC 4226.
12
13
Fields:
14
- key: CharField(max_length=80) - Hex-encoded secret key
15
- digits: PositiveSmallIntegerField - Number of digits (6 or 8)
16
- tolerance: PositiveSmallIntegerField(default=5) - Counter tolerance
17
- counter: BigIntegerField(default=0) - Next counter value
18
"""
19
20
key = models.CharField(max_length=80, validators=[hex_validator()])
21
digits = models.PositiveSmallIntegerField(choices=[(6, 6), (8, 8)], default=6)
22
tolerance = models.PositiveSmallIntegerField(default=5)
23
counter = models.BigIntegerField(default=0)
24
25
@property
26
def bin_key(self) -> bytes:
27
"""Secret key as binary string."""
28
29
@property
30
def config_url(self) -> str:
31
"""Configuration URL for QR codes and authenticator apps."""
32
33
def verify_token(self, token) -> bool:
34
"""
35
Verify HOTP token and advance counter.
36
37
Parameters:
38
- token: str - Token to verify
39
40
Returns:
41
bool - True if token is valid
42
"""
43
44
def get_throttle_factor(self) -> int:
45
"""Return throttle factor from settings."""
46
```
47
48
### Admin Interface
49
50
```python { .api }
51
class HOTPDeviceAdmin(admin.ModelAdmin):
52
"""Admin interface for HOTPDevice with QR code support."""
53
54
def qrcode_link(self, device):
55
"""Generate QR code link for device configuration."""
56
57
def config_view(self, request, pk):
58
"""Configuration view showing device setup information."""
59
60
def qrcode_view(self, request, pk):
61
"""QR code image view for device setup."""
62
```
63
64
## Usage Examples
65
66
### Creating HOTP Devices
67
68
```python
69
from django_otp.plugins.otp_hotp.models import HOTPDevice
70
71
# Create HOTP device
72
device = HOTPDevice.objects.create(
73
user=user,
74
name='Hardware Token',
75
tolerance=10, # Allow up to 10 counter values ahead
76
digits=8 # 8-digit tokens
77
)
78
79
print(f"Initial counter: {device.counter}")
80
print(f"Setup URL: {device.config_url}")
81
```
82
83
### Token Verification with Counter Management
84
85
```python
86
def verify_hotp_with_info(device, token):
87
"""Verify HOTP token and return verification info."""
88
89
old_counter = device.counter
90
is_valid = device.verify_token(token)
91
92
return {
93
'valid': is_valid,
94
'old_counter': old_counter,
95
'new_counter': device.counter,
96
'counter_advanced': device.counter - old_counter
97
}
98
99
# Usage
100
result = verify_hotp_with_info(device, '123456')
101
if result['valid']:
102
print(f"Counter advanced by {result['counter_advanced']}")
103
```
104
105
## Configuration Settings
106
107
```python
108
# settings.py
109
OTP_HOTP_THROTTLE_FACTOR = 1 # Throttling factor
110
OTP_HOTP_ISSUER = "My Company" # Issuer for QR codes
111
```