Skip to content

Commit d9727ca

Browse files
committed
Made algorithm class dependence on hash functions more direct.
- Algorithms now have SHA256, SHA384, and SHA512 static properties that refer to the callable that instantiates their hash class - All algorithms now expect a class (callable) as their hash_alg now. This behavior was inconsistent before.
1 parent 2d0e827 commit d9727ca

File tree

2 files changed

+28
-24
lines changed

2 files changed

+28
-24
lines changed

jwt/algorithms.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@ def _register_default_algorithms():
2323
Registers the algorithms that are implemented by the library.
2424
"""
2525
register_algorithm('none', NoneAlgorithm())
26-
register_algorithm('HS256', HMACAlgorithm(hashlib.sha256))
27-
register_algorithm('HS384', HMACAlgorithm(hashlib.sha384))
28-
register_algorithm('HS512', HMACAlgorithm(hashlib.sha512))
26+
register_algorithm('HS256', HMACAlgorithm(HMACAlgorithm.SHA256))
27+
register_algorithm('HS384', HMACAlgorithm(HMACAlgorithm.SHA384))
28+
register_algorithm('HS512', HMACAlgorithm(HMACAlgorithm.SHA512))
2929

3030
if has_crypto:
31-
register_algorithm('RS256', RSAAlgorithm(hashes.SHA256()))
32-
register_algorithm('RS384', RSAAlgorithm(hashes.SHA384()))
33-
register_algorithm('RS512', RSAAlgorithm(hashes.SHA512()))
31+
register_algorithm('RS256', RSAAlgorithm(RSAAlgorithm.SHA256))
32+
register_algorithm('RS384', RSAAlgorithm(RSAAlgorithm.SHA384))
33+
register_algorithm('RS512', RSAAlgorithm(RSAAlgorithm.SHA512))
3434

35-
register_algorithm('ES256', ECAlgorithm(hashes.SHA256()))
36-
register_algorithm('ES384', ECAlgorithm(hashes.SHA384()))
37-
register_algorithm('ES512', ECAlgorithm(hashes.SHA512()))
35+
register_algorithm('ES256', ECAlgorithm(ECAlgorithm.SHA256))
36+
register_algorithm('ES384', ECAlgorithm(ECAlgorithm.SHA384))
37+
register_algorithm('ES512', ECAlgorithm(ECAlgorithm.SHA512))
3838

3939

4040
class Algorithm(object):
@@ -86,6 +86,8 @@ class HMACAlgorithm(Algorithm):
8686
def __init__(self, hash_alg):
8787
self.hash_alg = hash_alg
8888

89+
SHA256, SHA384, SHA512 = hashlib.sha256, hashlib.sha384, hashlib.sha512
90+
8991
def prepare_key(self, key):
9092
if not isinstance(key, string_types) and not isinstance(key, bytes):
9193
raise TypeError('Expecting a string- or bytes-formatted key.')
@@ -110,7 +112,9 @@ class RSAAlgorithm(Algorithm):
110112
"""
111113

112114
def __init__(self, hash_alg):
113-
self.hash_alg = hash_alg
115+
self.hash_alg = hash_alg()
116+
117+
SHA256, SHA384, SHA512 = hashes.SHA256, hashes.SHA384, hashes.SHA512
114118

115119
def prepare_key(self, key):
116120
if isinstance(key, interfaces.RSAPrivateKey) or \
@@ -163,7 +167,9 @@ class ECAlgorithm(Algorithm):
163167
ECDSA and the specified hash function
164168
"""
165169
def __init__(self, hash_alg):
166-
self.hash_alg = hash_alg
170+
self.hash_alg = hash_alg()
171+
172+
SHA256, SHA384, SHA512 = hashes.SHA256, hashes.SHA384, hashes.SHA512
167173

168174
def prepare_key(self, key):
169175
if isinstance(key, interfaces.EllipticCurvePrivateKey) or \

tests/test_algorithms.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import base64
2-
import hashlib
32

43
from jwt.algorithms import Algorithm, HMACAlgorithm
54

65
from .compat import unittest
76
from .utils import ensure_bytes, ensure_unicode
87

98
try:
10-
from cryptography.hazmat.primitives import hashes
119
from jwt.algorithms import RSAAlgorithm, ECAlgorithm
1210

1311
has_crypto = True
@@ -38,7 +36,7 @@ def test_algorithm_should_throw_exception_if_verify_not_impl(self):
3836
algo.verify('message', 'key', 'signature')
3937

4038
def test_hmac_should_reject_nonstring_key(self):
41-
algo = HMACAlgorithm(hashlib.sha256())
39+
algo = HMACAlgorithm(HMACAlgorithm.SHA256)
4240

4341
with self.assertRaises(TypeError) as context:
4442
algo.prepare_key(object())
@@ -47,34 +45,34 @@ def test_hmac_should_reject_nonstring_key(self):
4745
self.assertEqual(str(exception), 'Expecting a string- or bytes-formatted key.')
4846

4947
def test_hmac_should_accept_unicode_key(self):
50-
algo = HMACAlgorithm(hashlib.sha256())
48+
algo = HMACAlgorithm(HMACAlgorithm.SHA256)
5149

5250
algo.prepare_key(ensure_unicode('awesome'))
5351

5452
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
5553
def test_rsa_should_parse_pem_public_key(self):
56-
algo = RSAAlgorithm(hashes.SHA256())
54+
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
5755

5856
with open('tests/keys/testkey2_rsa.pub.pem', 'r') as pem_key:
5957
algo.prepare_key(pem_key.read())
6058

6159
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
6260
def test_rsa_should_accept_unicode_key(self):
63-
algo = RSAAlgorithm(hashes.SHA256())
61+
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
6462

6563
with open('tests/keys/testkey_rsa', 'r') as rsa_key:
6664
algo.prepare_key(ensure_unicode(rsa_key.read()))
6765

6866
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
6967
def test_rsa_should_reject_non_string_key(self):
70-
algo = RSAAlgorithm(hashes.SHA256())
68+
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
7169

7270
with self.assertRaises(TypeError):
7371
algo.prepare_key(None)
7472

7573
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
7674
def test_rsa_verify_should_return_false_if_signature_invalid(self):
77-
algo = RSAAlgorithm(hashes.SHA256())
75+
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
7876

7977
jwt_message = ensure_bytes('Hello World!')
8078

@@ -96,7 +94,7 @@ def test_rsa_verify_should_return_false_if_signature_invalid(self):
9694

9795
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
9896
def test_rsa_verify_should_return_true_if_signature_valid(self):
99-
algo = RSAAlgorithm(hashes.SHA256())
97+
algo = RSAAlgorithm(RSAAlgorithm.SHA256)
10098

10199
jwt_message = ensure_bytes('Hello World!')
102100

@@ -116,21 +114,21 @@ def test_rsa_verify_should_return_true_if_signature_valid(self):
116114

117115
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
118116
def test_ec_should_reject_non_string_key(self):
119-
algo = ECAlgorithm(hashes.SHA256())
117+
algo = ECAlgorithm(ECAlgorithm.SHA256)
120118

121119
with self.assertRaises(TypeError):
122120
algo.prepare_key(None)
123121

124122
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
125123
def test_ec_should_accept_unicode_key(self):
126-
algo = ECAlgorithm(hashes.SHA256())
124+
algo = ECAlgorithm(ECAlgorithm.SHA256)
127125

128126
with open('tests/keys/testkey_ec', 'r') as ec_key:
129127
algo.prepare_key(ensure_unicode(ec_key.read()))
130128

131129
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
132130
def test_ec_verify_should_return_false_if_signature_invalid(self):
133-
algo = ECAlgorithm(hashes.SHA256())
131+
algo = ECAlgorithm(ECAlgorithm.SHA256)
134132

135133
jwt_message = ensure_bytes('Hello World!')
136134

@@ -150,7 +148,7 @@ def test_ec_verify_should_return_false_if_signature_invalid(self):
150148

151149
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
152150
def test_ec_verify_should_return_true_if_signature_valid(self):
153-
algo = ECAlgorithm(hashes.SHA256())
151+
algo = ECAlgorithm(ECAlgorithm.SHA256)
154152

155153
jwt_message = ensure_bytes('Hello World!')
156154

0 commit comments

Comments
 (0)