0
# JSON Web Algorithms (JWA)
1
2
Cryptographic signature algorithms implementing the JSON Web Algorithms specification (RFC 7518). Provides HMAC, RSA, and ECDSA signature algorithms with different hash functions for secure token signing and verification.
3
4
## Capabilities
5
6
### Signature Algorithm Instances
7
8
Pre-configured algorithm instances ready for immediate use in signing and verification operations.
9
10
```python { .api }
11
# RSASSA-PKCS1-v1_5 algorithms
12
RS256: JWASignature # RSA with SHA-256
13
RS384: JWASignature # RSA with SHA-384
14
RS512: JWASignature # RSA with SHA-512
15
16
# RSASSA-PSS algorithms
17
PS256: JWASignature # RSA-PSS with SHA-256 and MGF1
18
PS384: JWASignature # RSA-PSS with SHA-384 and MGF1
19
PS512: JWASignature # RSA-PSS with SHA-512 and MGF1
20
21
# ECDSA algorithms
22
ES256: JWASignature # ECDSA with P-256 curve and SHA-256
23
ES384: JWASignature # ECDSA with P-384 curve and SHA-384
24
ES512: JWASignature # ECDSA with P-521 curve and SHA-512
25
26
# HMAC algorithms
27
HS256: JWASignature # HMAC with SHA-256
28
HS384: JWASignature # HMAC with SHA-384
29
HS512: JWASignature # HMAC with SHA-512
30
```
31
32
#### Usage Examples
33
34
```python
35
from josepy import RS256, ES256, HS256, JWKRSA, JWKEC, JWKOct
36
from cryptography.hazmat.primitives.asymmetric import rsa, ec
37
from cryptography.hazmat.backends import default_backend
38
39
# RSA signing
40
private_key = rsa.generate_private_key(65537, 2048, default_backend())
41
jwk_rsa = JWKRSA(key=private_key)
42
message = b"Hello, World!"
43
44
# Sign with RS256
45
signature = RS256.sign(jwk_rsa.key, message)
46
print(f"RSA signature: {signature.hex()}")
47
48
# Verify signature
49
is_valid = RS256.verify(jwk_rsa.public_key().key, message, signature)
50
print(f"Signature valid: {is_valid}")
51
52
# ECDSA signing
53
ec_private_key = ec.generate_private_key(ec.SECP256R1(), default_backend())
54
jwk_ec = JWKEC(key=ec_private_key)
55
56
# Sign with ES256
57
ec_signature = ES256.sign(jwk_ec.key, message)
58
is_ec_valid = ES256.verify(jwk_ec.public_key().key, message, ec_signature)
59
print(f"ECDSA signature valid: {is_ec_valid}")
60
61
# HMAC signing
62
hmac_key = b"secret-key-bytes"
63
jwk_oct = JWKOct(key=hmac_key)
64
65
# Sign with HS256
66
hmac_signature = HS256.sign(jwk_oct.key, message)
67
is_hmac_valid = HS256.verify(jwk_oct.key, message, hmac_signature)
68
print(f"HMAC signature valid: {is_hmac_valid}")
69
```
70
71
### Base Algorithm Class
72
73
Abstract base class for all signature algorithms providing the core interface for signing and verification operations.
74
75
```python { .api }
76
class JWASignature:
77
"""Base class for JSON Web Signature Algorithms"""
78
79
def __init__(self, name: str): ...
80
81
def sign(self, key: Any, msg: bytes) -> bytes:
82
"""
83
Sign the message using the provided key.
84
85
Parameters:
86
- key: Cryptographic key appropriate for the algorithm
87
- msg: Message bytes to sign
88
89
Returns:
90
bytes: Digital signature
91
92
Raises:
93
cryptography.exceptions.InvalidSignature: If signing fails
94
"""
95
96
def verify(self, key: Any, msg: bytes, sig: bytes) -> bool:
97
"""
98
Verify the message and signature using the provided key.
99
100
Parameters:
101
- key: Cryptographic key appropriate for the algorithm
102
- msg: Original message bytes
103
- sig: Signature bytes to verify
104
105
Returns:
106
bool: True if signature is valid, False otherwise
107
"""
108
109
@classmethod
110
def from_json(cls, jobj: Any) -> 'JWASignature':
111
"""Deserialize algorithm from JSON string (algorithm name)"""
112
113
def to_partial_json(self) -> Any:
114
"""Serialize algorithm to JSON (returns algorithm name)"""
115
116
@classmethod
117
def register(cls, signature_cls: 'JWASignature') -> 'JWASignature':
118
"""Register algorithm class for JSON deserialization"""
119
120
name: str # Algorithm name (e.g., "RS256", "ES256", "HS256")
121
```
122
123
## Algorithm Details
124
125
### RSA Algorithms (RS256, RS384, RS512, PS256, PS384, PS512)
126
127
RSA-based signature algorithms supporting both PKCS#1 v1.5 and PSS padding schemes.
128
129
**Key Requirements:**
130
- RSA private key for signing
131
- RSA public key for verification
132
- Minimum 2048-bit key size recommended
133
134
**Algorithm Variations:**
135
- **RS series**: RSASSA-PKCS1-v1_5 with SHA hash functions
136
- **PS series**: RSASSA-PSS with SHA hash functions and MGF1 mask generation
137
138
### ECDSA Algorithms (ES256, ES384, ES512)
139
140
Elliptic Curve Digital Signature Algorithm with different curve sizes and hash functions.
141
142
**Key Requirements:**
143
- EC private key for signing
144
- EC public key for verification
145
- Curve must match algorithm specification:
146
- ES256: P-256 (secp256r1)
147
- ES384: P-384 (secp384r1)
148
- ES512: P-521 (secp521r1)
149
150
### HMAC Algorithms (HS256, HS384, HS512)
151
152
Hash-based Message Authentication Code using symmetric keys.
153
154
**Key Requirements:**
155
- Symmetric key (bytes) for both signing and verification
156
- Key should be at least as long as the hash output
157
- Same key used for both signing and verification
158
159
## Error Handling
160
161
All algorithms may raise cryptographic exceptions during signing and verification:
162
163
```python
164
import cryptography.exceptions
165
166
try:
167
signature = RS256.sign(key, message)
168
except cryptography.exceptions.InvalidSignature:
169
print("Signing failed - invalid key or message")
170
171
# Verification returns False on failure rather than raising exceptions
172
is_valid = RS256.verify(key, message, signature)
173
if not is_valid:
174
print("Signature verification failed")
175
```