0
# Cryptographic Utilities
1
2
Token signing and verification utilities supporting RSA and ECDSA algorithms. Provides the cryptographic foundation for JWT token creation, service account authentication, and credential verification.
3
4
## Capabilities
5
6
### Base Signer Interface
7
8
Abstract base class for cryptographic signers used in JWT token creation and service account authentication.
9
10
```python { .api }
11
class Signer(abc.ABC):
12
"""Abstract base class for cryptographic signers."""
13
14
@property
15
@abc.abstractmethod
16
def key_id(self):
17
"""
18
Optional[str]: The key ID used to identify the private key.
19
"""
20
21
@abc.abstractmethod
22
def sign(self, message):
23
"""
24
Sign a message.
25
26
Args:
27
message (Union[str, bytes]): The message to sign
28
29
Returns:
30
bytes: The signature
31
"""
32
33
class Verifier(abc.ABC):
34
"""Abstract base class for cryptographic verifiers."""
35
36
@abc.abstractmethod
37
def verify(self, message, signature):
38
"""
39
Verify a signature.
40
41
Args:
42
message (Union[str, bytes]): The message that was signed
43
signature (bytes): The signature to verify
44
45
Returns:
46
bool: True if the signature is valid, False otherwise
47
"""
48
```
49
50
### RSA Signers and Verifiers
51
52
RSA-based cryptographic operations for JWT signing and verification, supporting PKCS#1 v1.5 and PSS padding.
53
54
```python { .api }
55
class RSASigner(google.auth.crypt.Signer):
56
"""RSA-based signer for JWT tokens."""
57
58
def __init__(self, private_key, key_id=None):
59
"""
60
Initialize RSA signer.
61
62
Args:
63
private_key (Union[str, bytes, cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey]):
64
The RSA private key in PEM format or as a cryptography object
65
key_id (str): Optional key identifier
66
"""
67
68
@property
69
def key_id(self):
70
"""Optional[str]: The key ID for this signer."""
71
72
def sign(self, message):
73
"""
74
Sign a message using RSA-SHA256.
75
76
Args:
77
message (Union[str, bytes]): The message to sign
78
79
Returns:
80
bytes: The RSA signature
81
"""
82
83
@classmethod
84
def from_string(cls, key, key_id=None):
85
"""
86
Create an RSA signer from a PEM-encoded key string.
87
88
Args:
89
key (Union[str, bytes]): The private key in PEM format
90
key_id (str): Optional key identifier
91
92
Returns:
93
RSASigner: The constructed signer
94
"""
95
96
class RSAVerifier(google.auth.crypt.Verifier):
97
"""RSA-based verifier for JWT tokens."""
98
99
def __init__(self, public_key):
100
"""
101
Initialize RSA verifier.
102
103
Args:
104
public_key (Union[str, bytes, cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey]):
105
The RSA public key in PEM format or as a cryptography object
106
"""
107
108
def verify(self, message, signature):
109
"""
110
Verify an RSA signature.
111
112
Args:
113
message (Union[str, bytes]): The message that was signed
114
signature (bytes): The signature to verify
115
116
Returns:
117
bool: True if signature is valid, False otherwise
118
"""
119
120
@classmethod
121
def from_string(cls, key):
122
"""
123
Create an RSA verifier from a PEM-encoded key string.
124
125
Args:
126
key (Union[str, bytes]): The public key in PEM format
127
128
Returns:
129
RSAVerifier: The constructed verifier
130
"""
131
```
132
133
Usage example:
134
135
```python
136
from google.auth import crypt
137
138
# Create RSA signer from PEM key
139
private_key_pem = """-----BEGIN PRIVATE KEY-----
140
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...
141
-----END PRIVATE KEY-----"""
142
143
signer = crypt.RSASigner.from_string(private_key_pem, key_id='key-1')
144
145
# Sign a message
146
message = b"Hello, World!"
147
signature = signer.sign(message)
148
149
# Verify signature
150
public_key_pem = """-----BEGIN PUBLIC KEY-----
151
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
152
-----END PUBLIC KEY-----"""
153
154
verifier = crypt.RSAVerifier.from_string(public_key_pem)
155
is_valid = verifier.verify(message, signature)
156
print(f"Signature valid: {is_valid}")
157
```
158
159
### ECDSA Signers and Verifiers
160
161
ECDSA P-256 (ES256) cryptographic operations for JWT signing and verification.
162
163
```python { .api }
164
class ES256Signer(google.auth.crypt.Signer):
165
"""ECDSA P-256 signer for JWT tokens."""
166
167
def __init__(self, private_key, key_id=None):
168
"""
169
Initialize ECDSA P-256 signer.
170
171
Args:
172
private_key (Union[str, bytes, cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey]):
173
The ECDSA private key in PEM format or as a cryptography object
174
key_id (str): Optional key identifier
175
"""
176
177
@property
178
def key_id(self):
179
"""Optional[str]: The key ID for this signer."""
180
181
def sign(self, message):
182
"""
183
Sign a message using ECDSA P-256 with SHA-256.
184
185
Args:
186
message (Union[str, bytes]): The message to sign
187
188
Returns:
189
bytes: The ECDSA signature
190
"""
191
192
@classmethod
193
def from_string(cls, key, key_id=None):
194
"""
195
Create an ECDSA signer from a PEM-encoded key string.
196
197
Args:
198
key (Union[str, bytes]): The private key in PEM format
199
key_id (str): Optional key identifier
200
201
Returns:
202
ES256Signer: The constructed signer
203
"""
204
205
class ES256Verifier(google.auth.crypt.Verifier):
206
"""ECDSA P-256 verifier for JWT tokens."""
207
208
def __init__(self, public_key):
209
"""
210
Initialize ECDSA P-256 verifier.
211
212
Args:
213
public_key (Union[str, bytes, cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey]):
214
The ECDSA public key in PEM format or as a cryptography object
215
"""
216
217
def verify(self, message, signature):
218
"""
219
Verify an ECDSA signature.
220
221
Args:
222
message (Union[str, bytes]): The message that was signed
223
signature (bytes): The signature to verify
224
225
Returns:
226
bool: True if signature is valid, False otherwise
227
"""
228
229
@classmethod
230
def from_string(cls, key):
231
"""
232
Create an ECDSA verifier from a PEM-encoded key string.
233
234
Args:
235
key (Union[str, bytes]): The public key in PEM format
236
237
Returns:
238
ES256Verifier: The constructed verifier
239
"""
240
```
241
242
Usage example:
243
244
```python
245
from google.auth import crypt
246
247
# Create ECDSA signer
248
ecdsa_private_key = """-----BEGIN PRIVATE KEY-----
249
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg...
250
-----END PRIVATE KEY-----"""
251
252
signer = crypt.ES256Signer.from_string(ecdsa_private_key, key_id='ecdsa-key-1')
253
254
# Sign message
255
message = "Authentication request"
256
signature = signer.sign(message)
257
258
# Verify with corresponding public key
259
ecdsa_public_key = """-----BEGIN PUBLIC KEY-----
260
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
261
-----END PUBLIC KEY-----"""
262
263
verifier = crypt.ES256Verifier.from_string(ecdsa_public_key)
264
is_valid = verifier.verify(message, signature)
265
```
266
267
### Certificate Utilities
268
269
Utilities for working with X.509 certificates and extracting cryptographic information.
270
271
```python { .api }
272
def decode_key_id(key_id):
273
"""
274
Decode a key ID from a certificate or JWK.
275
276
Args:
277
key_id (Union[str, bytes]): The key ID to decode
278
279
Returns:
280
str: The decoded key ID
281
"""
282
283
def load_public_key_from_cert(cert_data):
284
"""
285
Load a public key from X.509 certificate data.
286
287
Args:
288
cert_data (Union[str, bytes]): The certificate in PEM or DER format
289
290
Returns:
291
Union[RSAPublicKey, EllipticCurvePublicKey]: The extracted public key
292
"""
293
294
def extract_subject_from_cert(cert_data):
295
"""
296
Extract the subject information from an X.509 certificate.
297
298
Args:
299
cert_data (Union[str, bytes]): The certificate in PEM or DER format
300
301
Returns:
302
Mapping[str, str]: The subject information
303
"""
304
```
305
306
### Service Account Key Utilities
307
308
Utilities for working with Google service account keys and extracting signers.
309
310
```python { .api }
311
def load_signer_from_info(info, require=None):
312
"""
313
Load a signer from service account info.
314
315
Args:
316
info (Mapping[str, str]): The service account info dictionary
317
require (Sequence[str]): Required fields in the info
318
319
Returns:
320
Tuple[google.auth.crypt.Signer, str]: The signer and service account email
321
322
Raises:
323
ValueError: If required fields are missing or invalid
324
"""
325
326
def load_signer_from_file(filename, require=None):
327
"""
328
Load a signer from a service account JSON file.
329
330
Args:
331
filename (str): Path to the service account JSON file
332
require (Sequence[str]): Required fields in the file
333
334
Returns:
335
Tuple[google.auth.crypt.Signer, str]: The signer and service account email
336
"""
337
```
338
339
Usage example:
340
341
```python
342
from google.auth import crypt
343
import json
344
345
# Load signer from service account file
346
signer, email = crypt.load_signer_from_file('/path/to/service-account.json')
347
print(f"Loaded signer for: {email}")
348
print(f"Key ID: {signer.key_id}")
349
350
# Load from info dictionary
351
with open('/path/to/service-account.json') as f:
352
info = json.load(f)
353
354
signer, email = crypt.load_signer_from_info(info)
355
356
# Use signer for JWT creation
357
from google.auth import jwt
358
import time
359
360
payload = {
361
'iss': email,
362
'sub': email,
363
'aud': 'https://example.googleapis.com/',
364
'iat': int(time.time()),
365
'exp': int(time.time()) + 3600
366
}
367
368
token = jwt.encode(payload, signer)
369
```
370
371
## Error Handling
372
373
```python { .api }
374
class MalformedError(google.auth.exceptions.GoogleAuthError):
375
"""Raised when cryptographic data is malformed."""
376
377
class InvalidKeyError(google.auth.exceptions.GoogleAuthError):
378
"""Raised when a cryptographic key is invalid."""
379
```
380
381
Common cryptographic error scenarios:
382
- Invalid or malformed private/public keys
383
- Unsupported key formats or algorithms
384
- Key size or curve parameter mismatches
385
- Signature verification failures
386
- Missing or invalid key IDs
387
- Certificate parsing errors
388
- Incompatible cryptographic library versions