swarmauri_crypto_jwe 0.3.0.dev5__tar.gz → 0.11.0.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {swarmauri_crypto_jwe-0.3.0.dev5 → swarmauri_crypto_jwe-0.11.0.dev1}/PKG-INFO +25 -18
- {swarmauri_crypto_jwe-0.3.0.dev5 → swarmauri_crypto_jwe-0.11.0.dev1}/README.md +18 -13
- {swarmauri_crypto_jwe-0.3.0.dev5 → swarmauri_crypto_jwe-0.11.0.dev1}/pyproject.toml +7 -6
- {swarmauri_crypto_jwe-0.3.0.dev5 → swarmauri_crypto_jwe-0.11.0.dev1}/swarmauri_crypto_jwe/JweCrypto.py +63 -23
- {swarmauri_crypto_jwe-0.3.0.dev5 → swarmauri_crypto_jwe-0.11.0.dev1}/LICENSE +0 -0
- {swarmauri_crypto_jwe-0.3.0.dev5 → swarmauri_crypto_jwe-0.11.0.dev1}/swarmauri_crypto_jwe/__init__.py +0 -0
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: swarmauri_crypto_jwe
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0.dev1
|
|
4
4
|
Summary: RFC 7516/7518 compliant JWE crypto provider for Swarmauri
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: swarmauri,sdk,standards,crypto,jwe,cryptography
|
|
8
8
|
Author: Jacob Stewart
|
|
9
9
|
Author-email: jacob@swarmauri.com
|
|
10
|
-
Requires-Python: >=3.10,<3.
|
|
10
|
+
Requires-Python: >=3.10,<3.15
|
|
11
11
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
12
|
Classifier: Natural Language :: English
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
17
13
|
Classifier: Development Status :: 3 - Alpha
|
|
18
14
|
Classifier: Topic :: Security :: Cryptography
|
|
19
15
|
Classifier: Intended Audience :: Developers
|
|
20
16
|
Classifier: Programming Language :: Python
|
|
21
17
|
Classifier: Programming Language :: Python :: 3
|
|
22
18
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
24
|
Provides-Extra: cbor
|
|
24
25
|
Provides-Extra: json
|
|
25
26
|
Requires-Dist: cbor2 ; extra == "cbor"
|
|
@@ -28,17 +29,21 @@ Requires-Dist: swarmauri_base
|
|
|
28
29
|
Requires-Dist: swarmauri_core
|
|
29
30
|
Description-Content-Type: text/markdown
|
|
30
31
|
|
|
31
|
-

|
|
32
33
|
|
|
33
34
|
<p align="center">
|
|
34
|
-
<a href="https://
|
|
35
|
-
|
|
36
|
-
<a href="https://
|
|
37
|
-
|
|
38
|
-
<a href="https://pypi.org/project/swarmauri_crypto_jwe/"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
<a href="https://pepy.tech/project/swarmauri_crypto_jwe/">
|
|
36
|
+
<img src="https://static.pepy.tech/badge/swarmauri_crypto_jwe/month" alt="PyPI - Downloads"/></a>
|
|
37
|
+
<a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_crypto_jwe/">
|
|
38
|
+
<img alt="Hits" src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_crypto_jwe.svg"/></a>
|
|
39
|
+
<a href="https://pypi.org/project/swarmauri_crypto_jwe/">
|
|
40
|
+
<img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue" alt="PyPI - Python Version"/></a>
|
|
41
|
+
<a href="https://pypi.org/project/swarmauri_crypto_jwe/">
|
|
42
|
+
<img src="https://img.shields.io/pypi/l/swarmauri_crypto_jwe" alt="PyPI - License"/></a>
|
|
43
|
+
<a href="https://pypi.org/project/swarmauri_crypto_jwe/">
|
|
44
|
+
<img src="https://img.shields.io/pypi/v/swarmauri_crypto_jwe?label=swarmauri_crypto_jwe&color=green" alt="PyPI - swarmauri_crypto_jwe"/></a>
|
|
45
|
+
<a href="https://discord.gg/N4UpBuQv8T">
|
|
46
|
+
<img src="https://img.shields.io/badge/Discord-Join%20Chat-5865F2?logo=discord&logoColor=white" alt="Discord"/></a></p>
|
|
42
47
|
|
|
43
48
|
## Swarmauri Crypto JWE
|
|
44
49
|
|
|
@@ -127,9 +132,9 @@ crypto = pm.load("swarmauri.cryptos", "JweCrypto")
|
|
|
127
132
|
|
|
128
133
|
**Parameters**
|
|
129
134
|
|
|
130
|
-
- `alg`
|
|
131
|
-
- `enc`
|
|
132
|
-
- `key`
|
|
135
|
+
- `alg` ? `JWAAlg` member describing the key management algorithm (`JWAAlg.RSA_OAEP_256`, `JWAAlg.DIR`, etc.).
|
|
136
|
+
- `enc` ? `JWAAlg` member describing the content encryption algorithm (`JWAAlg.A256GCM`, `JWAAlg.A128GCM`, etc.).
|
|
137
|
+
- `key` ? mapping containing the key material used for encryption:
|
|
133
138
|
- `{"k": bytes}` for direct symmetric keys (`dir`).
|
|
134
139
|
- `{"pub": rsa_public_key}` for RSA OAEP, where the public key may be PEM bytes or an `RSAPublicKey` instance.
|
|
135
140
|
- `{"pub": ec_public_key}` for ECDH-ES with PEM, JWK, or key objects.
|
|
@@ -146,3 +151,5 @@ The provider is registered under the `swarmauri.cryptos` entry point as `JweCryp
|
|
|
146
151
|
If you want to contribute to swarmauri-sdk, read up on our
|
|
147
152
|
[guidelines for contributing](https://github.com/swarmauri/swarmauri-sdk/blob/master/CONTRIBUTING.md)
|
|
148
153
|
that will help you get started.
|
|
154
|
+
|
|
155
|
+
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<a href="https://
|
|
5
|
-
|
|
6
|
-
<a href="https://
|
|
7
|
-
|
|
8
|
-
<a href="https://pypi.org/project/swarmauri_crypto_jwe/"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
<a href="https://pepy.tech/project/swarmauri_crypto_jwe/">
|
|
5
|
+
<img src="https://static.pepy.tech/badge/swarmauri_crypto_jwe/month" alt="PyPI - Downloads"/></a>
|
|
6
|
+
<a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_crypto_jwe/">
|
|
7
|
+
<img alt="Hits" src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_crypto_jwe.svg"/></a>
|
|
8
|
+
<a href="https://pypi.org/project/swarmauri_crypto_jwe/">
|
|
9
|
+
<img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue" alt="PyPI - Python Version"/></a>
|
|
10
|
+
<a href="https://pypi.org/project/swarmauri_crypto_jwe/">
|
|
11
|
+
<img src="https://img.shields.io/pypi/l/swarmauri_crypto_jwe" alt="PyPI - License"/></a>
|
|
12
|
+
<a href="https://pypi.org/project/swarmauri_crypto_jwe/">
|
|
13
|
+
<img src="https://img.shields.io/pypi/v/swarmauri_crypto_jwe?label=swarmauri_crypto_jwe&color=green" alt="PyPI - swarmauri_crypto_jwe"/></a>
|
|
14
|
+
<a href="https://discord.gg/N4UpBuQv8T">
|
|
15
|
+
<img src="https://img.shields.io/badge/Discord-Join%20Chat-5865F2?logo=discord&logoColor=white" alt="Discord"/></a></p>
|
|
12
16
|
|
|
13
17
|
## Swarmauri Crypto JWE
|
|
14
18
|
|
|
@@ -97,9 +101,9 @@ crypto = pm.load("swarmauri.cryptos", "JweCrypto")
|
|
|
97
101
|
|
|
98
102
|
**Parameters**
|
|
99
103
|
|
|
100
|
-
- `alg`
|
|
101
|
-
- `enc`
|
|
102
|
-
- `key`
|
|
104
|
+
- `alg` ? `JWAAlg` member describing the key management algorithm (`JWAAlg.RSA_OAEP_256`, `JWAAlg.DIR`, etc.).
|
|
105
|
+
- `enc` ? `JWAAlg` member describing the content encryption algorithm (`JWAAlg.A256GCM`, `JWAAlg.A128GCM`, etc.).
|
|
106
|
+
- `key` ? mapping containing the key material used for encryption:
|
|
103
107
|
- `{"k": bytes}` for direct symmetric keys (`dir`).
|
|
104
108
|
- `{"pub": rsa_public_key}` for RSA OAEP, where the public key may be PEM bytes or an `RSAPublicKey` instance.
|
|
105
109
|
- `{"pub": ec_public_key}` for ECDH-ES with PEM, JWK, or key objects.
|
|
@@ -115,4 +119,5 @@ The provider is registered under the `swarmauri.cryptos` entry point as `JweCryp
|
|
|
115
119
|
|
|
116
120
|
If you want to contribute to swarmauri-sdk, read up on our
|
|
117
121
|
[guidelines for contributing](https://github.com/swarmauri/swarmauri-sdk/blob/master/CONTRIBUTING.md)
|
|
118
|
-
that will help you get started.
|
|
122
|
+
that will help you get started.
|
|
123
|
+
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "swarmauri_crypto_jwe"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.11.0.dev1"
|
|
4
4
|
description = "RFC 7516/7518 compliant JWE crypto provider for Swarmauri"
|
|
5
5
|
license = "Apache-2.0"
|
|
6
6
|
readme = "README.md"
|
|
7
|
-
requires-python = ">=3.10,<3.
|
|
7
|
+
requires-python = ">=3.10,<3.15"
|
|
8
8
|
authors = [{ name = "Jacob Stewart", email = "jacob@swarmauri.com" }]
|
|
9
9
|
classifiers = [
|
|
10
10
|
"License :: OSI Approved :: Apache Software License",
|
|
11
11
|
"Natural Language :: English",
|
|
12
|
-
"Programming Language :: Python :: 3.10",
|
|
13
|
-
"Programming Language :: Python :: 3.11",
|
|
14
|
-
"Programming Language :: Python :: 3.12",
|
|
15
|
-
"Programming Language :: Python :: 3.13",
|
|
16
12
|
"Development Status :: 3 - Alpha",
|
|
17
13
|
"Topic :: Security :: Cryptography",
|
|
18
14
|
"Intended Audience :: Developers",
|
|
19
15
|
"Programming Language :: Python",
|
|
20
16
|
"Programming Language :: Python :: 3",
|
|
21
17
|
"Programming Language :: Python :: 3 :: Only",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
22
23
|
]
|
|
23
24
|
dependencies = [
|
|
24
25
|
"swarmauri_core",
|
|
@@ -47,7 +47,9 @@ def _cek_len_for_enc(enc: JWAAlg) -> int:
|
|
|
47
47
|
return 24
|
|
48
48
|
if enc == JWAAlg.A256GCM:
|
|
49
49
|
return 32
|
|
50
|
-
raise ValueError(
|
|
50
|
+
raise ValueError(
|
|
51
|
+
f"Unsupported enc '{enc.value}'. Use A128GCM/A192GCM/A256GCM."
|
|
52
|
+
)
|
|
51
53
|
|
|
52
54
|
|
|
53
55
|
def _hash_for_oaep(alg: JWAAlg):
|
|
@@ -68,7 +70,9 @@ def _compute_aad(protected_b64: str, aad_bytes: Optional[bytes]) -> bytes:
|
|
|
68
70
|
return (protected_b64 + "." + _b64u(aad_bytes)).encode("ascii")
|
|
69
71
|
|
|
70
72
|
|
|
71
|
-
def _jwk_ec_public_numbers(
|
|
73
|
+
def _jwk_ec_public_numbers(
|
|
74
|
+
jwk: Mapping[str, Any],
|
|
75
|
+
) -> ec.EllipticCurvePublicNumbers:
|
|
72
76
|
crv = jwk.get("crv")
|
|
73
77
|
curve_map = {
|
|
74
78
|
"P-256": ec.SECP256R1(),
|
|
@@ -85,7 +89,11 @@ def _jwk_ec_public_numbers(jwk: Mapping[str, Any]) -> ec.EllipticCurvePublicNumb
|
|
|
85
89
|
def _ec_jwk_from_public_key(pk: ec.EllipticCurvePublicKey) -> Dict[str, Any]:
|
|
86
90
|
numbers = pk.public_numbers()
|
|
87
91
|
crv = pk.curve.name
|
|
88
|
-
crv_map = {
|
|
92
|
+
crv_map = {
|
|
93
|
+
"secp256r1": "P-256",
|
|
94
|
+
"secp384r1": "P-384",
|
|
95
|
+
"secp521r1": "P-521",
|
|
96
|
+
}
|
|
89
97
|
if crv not in crv_map:
|
|
90
98
|
raise ValueError(f"Unsupported EC curve: {crv}")
|
|
91
99
|
size = (pk.curve.key_size + 7) // 8
|
|
@@ -96,7 +104,8 @@ def _ec_jwk_from_public_key(pk: ec.EllipticCurvePublicKey) -> Dict[str, Any]:
|
|
|
96
104
|
|
|
97
105
|
def _x25519_jwk_from_public_key(pk: x25519.X25519PublicKey) -> Dict[str, Any]:
|
|
98
106
|
raw = pk.public_bytes(
|
|
99
|
-
encoding=serialization.Encoding.Raw,
|
|
107
|
+
encoding=serialization.Encoding.Raw,
|
|
108
|
+
format=serialization.PublicFormat.Raw,
|
|
100
109
|
)
|
|
101
110
|
return {"kty": "OKP", "crv": "X25519", "x": _b64u(raw)}
|
|
102
111
|
|
|
@@ -105,7 +114,9 @@ def _load_rsa_public(key: Any) -> rsa.RSAPublicKey:
|
|
|
105
114
|
if isinstance(key, rsa.RSAPublicKey):
|
|
106
115
|
return key
|
|
107
116
|
if isinstance(key, (bytes, bytearray, str)):
|
|
108
|
-
data =
|
|
117
|
+
data = (
|
|
118
|
+
key if isinstance(key, (bytes, bytearray)) else key.encode("utf-8")
|
|
119
|
+
)
|
|
109
120
|
pk = load_pem_public_key(data)
|
|
110
121
|
if not isinstance(pk, rsa.RSAPublicKey):
|
|
111
122
|
raise TypeError("PEM provided is not an RSA public key")
|
|
@@ -128,7 +139,9 @@ def _load_rsa_private(
|
|
|
128
139
|
elif isinstance(password, (bytes, bytearray)):
|
|
129
140
|
pwd = bytes(password)
|
|
130
141
|
if isinstance(key, (bytes, bytearray, str)):
|
|
131
|
-
data =
|
|
142
|
+
data = (
|
|
143
|
+
key if isinstance(key, (bytes, bytearray)) else key.encode("utf-8")
|
|
144
|
+
)
|
|
132
145
|
sk = load_pem_private_key(data, password=pwd)
|
|
133
146
|
if not isinstance(sk, rsa.RSAPrivateKey):
|
|
134
147
|
raise TypeError("PEM provided is not an RSA private key")
|
|
@@ -146,7 +159,7 @@ def _load_ecdh_recipient_public(jwk_or_pem: Any) -> Tuple[str, Any]:
|
|
|
146
159
|
x = _b64u_dec(jwk_or_pem["x"])
|
|
147
160
|
return "X25519", x25519.X25519PublicKey.from_public_bytes(x)
|
|
148
161
|
raise ValueError(
|
|
149
|
-
f"Unsupported JWK kty/crv for ECDH-ES: {kty}/{jwk_or_pem.get('crv')}"
|
|
162
|
+
f"Unsupported JWK kty/crv for ECDH-ES: {kty}/{jwk_or_pem.get('crv')}" # noqa: E501
|
|
150
163
|
)
|
|
151
164
|
if isinstance(jwk_or_pem, (bytes, bytearray, str)):
|
|
152
165
|
data = (
|
|
@@ -225,7 +238,8 @@ class JweCrypto:
|
|
|
225
238
|
) -> JWECompact:
|
|
226
239
|
"""Encrypt a payload into a compact JWE string.
|
|
227
240
|
|
|
228
|
-
payload (Union[bytes, str, Mapping[str, Any]]): Data to encrypt.
|
|
241
|
+
payload (Union[bytes, str, Mapping[str, Any]]): Data to encrypt.
|
|
242
|
+
Strings and
|
|
229
243
|
mappings are encoded as UTF-8 JSON.
|
|
230
244
|
alg (JWAAlg): Key management algorithm.
|
|
231
245
|
enc (JWAAlg): Content encryption algorithm.
|
|
@@ -259,11 +273,13 @@ class JweCrypto:
|
|
|
259
273
|
if alg == JWAAlg.DIR:
|
|
260
274
|
secret = key.get("k")
|
|
261
275
|
secret_b = (
|
|
262
|
-
secret.encode("utf-8")
|
|
276
|
+
secret.encode("utf-8")
|
|
277
|
+
if isinstance(secret, str)
|
|
278
|
+
else bytes(secret)
|
|
263
279
|
)
|
|
264
280
|
if len(secret_b) != _cek_len_for_enc(enc):
|
|
265
281
|
raise ValueError(
|
|
266
|
-
f"'dir' key size must equal enc key size ({_cek_len_for_enc(enc)} bytes)"
|
|
282
|
+
f"'dir' key size must equal enc key size ({_cek_len_for_enc(enc)} bytes)" # noqa: E501
|
|
267
283
|
)
|
|
268
284
|
cek = secret_b
|
|
269
285
|
elif alg in (JWAAlg.RSA_OAEP, JWAAlg.RSA_OAEP_256):
|
|
@@ -351,19 +367,23 @@ class JweCrypto:
|
|
|
351
367
|
|
|
352
368
|
jwe (JWECompact): Serialized JWE to decode.
|
|
353
369
|
dir_key (Union[bytes, str]): Symmetric key when ``alg='dir'`` is used.
|
|
354
|
-
rsa_private_pem (Union[str, bytes]): RSA private key in PEM encoding
|
|
370
|
+
rsa_private_pem (Union[str, bytes]): RSA private key in PEM encoding
|
|
371
|
+
for
|
|
355
372
|
RSA-OAEP algorithms.
|
|
356
373
|
rsa_private_password (Union[str, bytes]): Password for the RSA key.
|
|
357
374
|
ecdh_private_key (Any): Private key for ECDH-ES.
|
|
358
375
|
expected_algs (Iterable[JWAAlg]): Allowed algorithm values.
|
|
359
376
|
expected_encs (Iterable[JWAAlg]): Allowed encryption values.
|
|
360
377
|
aad (Union[bytes, str]): Additional authenticated data.
|
|
361
|
-
RETURNS (JweDecryptResult): Header and plaintext of the decrypted
|
|
378
|
+
RETURNS (JweDecryptResult): Header and plaintext of the decrypted
|
|
379
|
+
token.
|
|
362
380
|
"""
|
|
363
381
|
|
|
364
382
|
parts = jwe.split(".")
|
|
365
383
|
if len(parts) != 5:
|
|
366
|
-
raise ValueError(
|
|
384
|
+
raise ValueError(
|
|
385
|
+
"Invalid JWE compact: expected 5 dot-separated parts."
|
|
386
|
+
)
|
|
367
387
|
b64_prot, b64_ekey, b64_iv, b64_ct, b64_tag = parts
|
|
368
388
|
|
|
369
389
|
header = json.loads(_b64u_dec(b64_prot))
|
|
@@ -389,33 +409,49 @@ class JweCrypto:
|
|
|
389
409
|
if dir_key is None:
|
|
390
410
|
raise ValueError("dir_key is required for alg='dir'.")
|
|
391
411
|
cek = (
|
|
392
|
-
dir_key.encode("utf-8")
|
|
412
|
+
dir_key.encode("utf-8")
|
|
413
|
+
if isinstance(dir_key, str)
|
|
414
|
+
else bytes(dir_key)
|
|
393
415
|
)
|
|
394
416
|
if len(cek) != _cek_len_for_enc(enc):
|
|
395
417
|
raise ValueError("dir_key length mismatch for enc.")
|
|
396
418
|
elif alg in (JWAAlg.RSA_OAEP, JWAAlg.RSA_OAEP_256):
|
|
397
419
|
if rsa_private_pem is None:
|
|
398
|
-
raise ValueError(
|
|
399
|
-
|
|
420
|
+
raise ValueError(
|
|
421
|
+
"rsa_private_pem is required for RSA-OAEP decryption."
|
|
422
|
+
)
|
|
423
|
+
sk = _load_rsa_private(
|
|
424
|
+
rsa_private_pem, password=rsa_private_password
|
|
425
|
+
)
|
|
400
426
|
ekey = _b64u_dec(b64_ekey)
|
|
401
427
|
hash_alg = _hash_for_oaep(alg)
|
|
402
428
|
cek = sk.decrypt(
|
|
403
429
|
ekey,
|
|
404
430
|
padding.OAEP(
|
|
405
|
-
mgf=padding.MGF1(algorithm=hash_alg),
|
|
431
|
+
mgf=padding.MGF1(algorithm=hash_alg),
|
|
432
|
+
algorithm=hash_alg,
|
|
433
|
+
label=None,
|
|
406
434
|
),
|
|
407
435
|
)
|
|
408
436
|
elif alg == JWAAlg.ECDH_ES:
|
|
409
437
|
if ecdh_private_key is None:
|
|
410
|
-
raise ValueError(
|
|
438
|
+
raise ValueError(
|
|
439
|
+
"ecdh_private_key is required for ECDH-ES decryption."
|
|
440
|
+
)
|
|
411
441
|
epk = header.get("epk")
|
|
412
442
|
if not isinstance(epk, Mapping):
|
|
413
|
-
raise ValueError(
|
|
443
|
+
raise ValueError(
|
|
444
|
+
"Missing/invalid 'epk' in JWE header for ECDH-ES."
|
|
445
|
+
)
|
|
414
446
|
if epk.get("kty") == "OKP" and epk.get("crv") == "X25519":
|
|
415
447
|
if not isinstance(ecdh_private_key, x25519.X25519PrivateKey):
|
|
416
|
-
raise TypeError(
|
|
448
|
+
raise TypeError(
|
|
449
|
+
"ECDH-ES with X25519 requires an X25519PrivateKey."
|
|
450
|
+
)
|
|
417
451
|
z = ecdh_private_key.exchange(
|
|
418
|
-
x25519.X25519PublicKey.from_public_bytes(
|
|
452
|
+
x25519.X25519PublicKey.from_public_bytes(
|
|
453
|
+
_b64u_dec(epk["x"])
|
|
454
|
+
)
|
|
419
455
|
)
|
|
420
456
|
elif epk.get("kty") == "EC":
|
|
421
457
|
crv = epk.get("crv")
|
|
@@ -426,7 +462,9 @@ class JweCrypto:
|
|
|
426
462
|
}.get(crv)
|
|
427
463
|
if curve is None:
|
|
428
464
|
raise ValueError(f"Unsupported EC curve in epk: {crv}")
|
|
429
|
-
if not isinstance(
|
|
465
|
+
if not isinstance(
|
|
466
|
+
ecdh_private_key, ec.EllipticCurvePrivateKey
|
|
467
|
+
):
|
|
430
468
|
raise TypeError(
|
|
431
469
|
"ECDH-ES with EC requires an EllipticCurvePrivateKey."
|
|
432
470
|
)
|
|
@@ -454,7 +492,9 @@ class JweCrypto:
|
|
|
454
492
|
try:
|
|
455
493
|
pt = zlib.decompress(pt)
|
|
456
494
|
except Exception as exc: # noqa: BLE001
|
|
457
|
-
raise ValueError(
|
|
495
|
+
raise ValueError(
|
|
496
|
+
f"Failed to decompress (zip=DEF): {exc}"
|
|
497
|
+
) from exc
|
|
458
498
|
|
|
459
499
|
return JweDecryptResult(header=header, plaintext=pt)
|
|
460
500
|
|
|
File without changes
|
|
File without changes
|