0
# Client-Side Encryption
1
2
Advanced S3 client-side encryption capabilities for secure data storage with async support. The S3 CSE (Client-Side Encryption) functionality provides encryption and decryption of data before sending to or receiving from S3, ensuring data security at rest and in transit.
3
4
## Capabilities
5
6
### S3 CSE Client
7
8
Main client-side encryption client that wraps S3 operations with encryption/decryption capabilities.
9
10
```python { .api }
11
class S3CSEClient:
12
def __init__(
13
self,
14
s3_client,
15
kms_key_id: str = None,
16
encryption_key = None,
17
key_wrap_algorithm: str = None
18
):
19
"""
20
Initialize S3 client-side encryption client.
21
22
Parameters:
23
- s3_client: Underlying S3 client
24
- kms_key_id: KMS key ID for key encryption
25
- encryption_key: Master encryption key
26
- key_wrap_algorithm: Algorithm for key wrapping
27
"""
28
29
async def __aenter__(self):
30
"""
31
Async context manager entry.
32
33
Returns:
34
self: The S3CSEClient instance
35
"""
36
37
async def __aexit__(self, exc_type, exc_val, exc_tb):
38
"""
39
Async context manager exit.
40
41
Parameters:
42
- exc_type: Exception type if an exception occurred
43
- exc_val: Exception value if an exception occurred
44
- exc_tb: Exception traceback if an exception occurred
45
"""
46
47
async def put_object(self, **kwargs):
48
"""
49
Put an encrypted object to S3.
50
51
Parameters:
52
- Bucket: S3 bucket name
53
- Key: S3 object key
54
- Body: Object body (will be encrypted)
55
- **kwargs: Additional S3 put_object parameters
56
57
Returns:
58
Response from S3 put_object operation
59
"""
60
61
async def get_object(self, **kwargs):
62
"""
63
Get and decrypt an object from S3.
64
65
Parameters:
66
- Bucket: S3 bucket name
67
- Key: S3 object key
68
- **kwargs: Additional S3 get_object parameters
69
70
Returns:
71
Decrypted response with Body containing decrypted data
72
"""
73
74
async def upload_file(
75
self,
76
filename: str,
77
bucket: str,
78
key: str,
79
**kwargs
80
):
81
"""
82
Upload and encrypt a file to S3.
83
84
Parameters:
85
- filename: Local file path
86
- bucket: S3 bucket name
87
- key: S3 object key
88
- **kwargs: Additional upload parameters
89
"""
90
91
async def download_file(
92
self,
93
bucket: str,
94
key: str,
95
filename: str,
96
**kwargs
97
):
98
"""
99
Download and decrypt a file from S3.
100
101
Parameters:
102
- bucket: S3 bucket name
103
- key: S3 object key
104
- filename: Local file path to save decrypted data
105
- **kwargs: Additional download parameters
106
"""
107
```
108
109
### S3 CSE Bucket
110
111
Bucket resource wrapper with client-side encryption support.
112
113
```python { .api }
114
class S3CSEBucket:
115
def __init__(self, bucket_resource, cse_client):
116
"""
117
Initialize S3 CSE bucket wrapper.
118
119
Parameters:
120
- bucket_resource: S3 bucket resource
121
- cse_client: S3CSEClient instance
122
"""
123
124
async def __aenter__(self):
125
"""
126
Async context manager entry.
127
128
Returns:
129
self: The S3CSEBucket instance
130
"""
131
132
async def __aexit__(self, exc_type, exc_val, exc_tb):
133
"""
134
Async context manager exit.
135
"""
136
137
async def put_object(self, key: str, body, **kwargs):
138
"""
139
Put encrypted object to this bucket.
140
141
Parameters:
142
- key: S3 object key
143
- body: Object body (will be encrypted)
144
- **kwargs: Additional parameters
145
"""
146
147
async def get_object(self, key: str, **kwargs):
148
"""
149
Get and decrypt object from this bucket.
150
151
Parameters:
152
- key: S3 object key
153
- **kwargs: Additional parameters
154
155
Returns:
156
Decrypted object data
157
"""
158
```
159
160
### S3 CSE Object
161
162
Object resource wrapper with client-side encryption support.
163
164
```python { .api }
165
class S3CSEObject:
166
def __init__(self, object_resource, cse_client):
167
"""
168
Initialize S3 CSE object wrapper.
169
170
Parameters:
171
- object_resource: S3 object resource
172
- cse_client: S3CSEClient instance
173
"""
174
175
async def __aenter__(self):
176
"""
177
Async context manager entry.
178
179
Returns:
180
self: The S3CSEObject instance
181
"""
182
183
async def __aexit__(self, exc_type, exc_val, exc_tb):
184
"""
185
Async context manager exit.
186
"""
187
188
async def put(self, body, **kwargs):
189
"""
190
Put encrypted data to this object.
191
192
Parameters:
193
- body: Object body (will be encrypted)
194
- **kwargs: Additional parameters
195
"""
196
197
async def get(self, **kwargs):
198
"""
199
Get and decrypt this object's data.
200
201
Parameters:
202
- **kwargs: Additional parameters
203
204
Returns:
205
Decrypted object data
206
"""
207
```
208
209
### Encryption Utilities
210
211
Supporting classes and functions for encryption operations.
212
213
```python { .api }
214
class DummyAIOFile:
215
def __init__(self, data: bytes):
216
"""
217
Async file wrapper for encrypted data.
218
219
Parameters:
220
- data: Encrypted/decrypted byte data
221
"""
222
223
async def read(self, n: int = -1) -> bytes:
224
"""
225
Read data from the file.
226
227
Parameters:
228
- n: Number of bytes to read (-1 for all)
229
230
Returns:
231
Byte data
232
"""
233
234
async def readany(self) -> bytes:
235
"""
236
Read any available data.
237
238
Returns:
239
Available byte data
240
"""
241
242
async def readexactly(self, n: int) -> bytes:
243
"""
244
Read exactly n bytes.
245
246
Parameters:
247
- n: Number of bytes to read
248
249
Returns:
250
Exactly n bytes of data
251
"""
252
253
async def readchunk(self) -> tuple:
254
"""
255
Read a chunk of data.
256
257
Returns:
258
Tuple of (data, is_eof)
259
"""
260
```
261
262
## Usage Examples
263
264
### Basic Encryption Setup
265
266
```python
267
import aioboto3
268
from aioboto3.s3.cse import S3CSEClient
269
270
async def basic_cse_usage():
271
session = aioboto3.Session()
272
273
# Create regular S3 client first
274
async with session.client('s3', region_name='us-east-1') as s3_client:
275
# Create CSE client with KMS key
276
cse_client = S3CSEClient(
277
s3_client=s3_client,
278
kms_key_id='arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012'
279
)
280
281
async with cse_client:
282
# Upload encrypted data
283
await cse_client.put_object(
284
Bucket='my-secure-bucket',
285
Key='sensitive-data.txt',
286
Body=b'This is sensitive information'
287
)
288
289
# Download and decrypt data
290
response = await cse_client.get_object(
291
Bucket='my-secure-bucket',
292
Key='sensitive-data.txt'
293
)
294
295
decrypted_data = await response['Body'].read()
296
print(f"Decrypted: {decrypted_data}")
297
```
298
299
### File Upload/Download with Encryption
300
301
```python
302
async def file_operations_with_encryption():
303
session = aioboto3.Session()
304
305
async with session.client('s3', region_name='us-east-1') as s3_client:
306
cse_client = S3CSEClient(
307
s3_client=s3_client,
308
kms_key_id='your-kms-key-id'
309
)
310
311
async with cse_client:
312
# Upload encrypted file
313
await cse_client.upload_file(
314
'/path/to/sensitive/document.pdf',
315
'my-secure-bucket',
316
'documents/encrypted-document.pdf'
317
)
318
319
# Download and decrypt file
320
await cse_client.download_file(
321
'my-secure-bucket',
322
'documents/encrypted-document.pdf',
323
'/path/to/decrypted/document.pdf'
324
)
325
```
326
327
### Using Master Encryption Key
328
329
```python
330
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
331
import os
332
333
async def master_key_encryption():
334
session = aioboto3.Session()
335
336
# Generate or load master key
337
master_key = AESGCM.generate_key(bit_length=256)
338
339
async with session.client('s3', region_name='us-east-1') as s3_client:
340
cse_client = S3CSEClient(
341
s3_client=s3_client,
342
encryption_key=master_key,
343
key_wrap_algorithm='AES-GCM'
344
)
345
346
async with cse_client:
347
# Encrypt and upload data
348
sensitive_data = "Secret business information"
349
350
await cse_client.put_object(
351
Bucket='my-secure-bucket',
352
Key='business/secret.txt',
353
Body=sensitive_data.encode()
354
)
355
356
# Decrypt and retrieve data
357
response = await cse_client.get_object(
358
Bucket='my-secure-bucket',
359
Key='business/secret.txt'
360
)
361
362
decrypted_content = await response['Body'].read()
363
print(f"Retrieved: {decrypted_content.decode()}")
364
```
365
366
### Batch Operations with Encryption
367
368
```python
369
async def batch_encrypted_operations():
370
session = aioboto3.Session()
371
372
async with session.client('s3', region_name='us-east-1') as s3_client:
373
cse_client = S3CSEClient(
374
s3_client=s3_client,
375
kms_key_id='your-kms-key-id'
376
)
377
378
async with cse_client:
379
# Upload multiple encrypted files
380
files_to_encrypt = [
381
('file1.txt', b'Content of file 1'),
382
('file2.txt', b'Content of file 2'),
383
('file3.txt', b'Content of file 3')
384
]
385
386
for filename, content in files_to_encrypt:
387
await cse_client.put_object(
388
Bucket='my-secure-bucket',
389
Key=f'encrypted/{filename}',
390
Body=content
391
)
392
393
# Download and decrypt all files
394
for filename, _ in files_to_encrypt:
395
response = await cse_client.get_object(
396
Bucket='my-secure-bucket',
397
Key=f'encrypted/{filename}'
398
)
399
400
decrypted = await response['Body'].read()
401
print(f"{filename}: {decrypted}")
402
```
403
404
### Error Handling with CSE
405
406
```python
407
import botocore.exceptions
408
from cryptography.exceptions import InvalidTag
409
410
async def cse_error_handling():
411
session = aioboto3.Session()
412
413
try:
414
async with session.client('s3', region_name='us-east-1') as s3_client:
415
cse_client = S3CSEClient(
416
s3_client=s3_client,
417
kms_key_id='your-kms-key-id'
418
)
419
420
async with cse_client:
421
response = await cse_client.get_object(
422
Bucket='my-secure-bucket',
423
Key='encrypted-file.txt'
424
)
425
426
data = await response['Body'].read()
427
428
except InvalidTag:
429
print("Decryption failed - invalid authentication tag")
430
431
except botocore.exceptions.ClientError as e:
432
error_code = e.response['Error']['Code']
433
434
if error_code == 'AccessDenied':
435
print("Access denied - check KMS key permissions")
436
elif error_code == 'NoSuchKey':
437
print("Encrypted object not found")
438
else:
439
print(f"S3 error: {error_code}")
440
441
except Exception as e:
442
print(f"Encryption/decryption error: {e}")
443
```
444
445
### Configuring Encryption Algorithms
446
447
```python
448
async def advanced_encryption_config():
449
session = aioboto3.Session()
450
451
async with session.client('s3', region_name='us-east-1') as s3_client:
452
# Configure with specific encryption settings
453
cse_client = S3CSEClient(
454
s3_client=s3_client,
455
kms_key_id='your-kms-key-id',
456
key_wrap_algorithm='AES-GCM' # Specify key wrapping algorithm
457
)
458
459
async with cse_client:
460
# Upload with metadata about encryption
461
await cse_client.put_object(
462
Bucket='my-secure-bucket',
463
Key='metadata-encrypted.txt',
464
Body=b'Data with encryption metadata',
465
Metadata={
466
'encryption-info': 'client-side-encrypted',
467
'algorithm': 'AES-GCM'
468
}
469
)
470
```