-
Notifications
You must be signed in to change notification settings - Fork 1
/
signatures.py
85 lines (78 loc) · 3.43 KB
/
signatures.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import hmac
import hashlib
import base64
import utils
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.serialization import (
load_pem_private_key, load_pem_public_key, load_ssh_public_key
)
from cryptography.hazmat.primitives.asymmetric.rsa import (
RSAPrivateKey, RSAPublicKey, RSAPrivateNumbers, RSAPublicNumbers,
rsa_recover_prime_factors, rsa_crt_dmp1, rsa_crt_dmq1, rsa_crt_iqmp
)
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.hashes import HashAlgorithm, SHA256
from cryptography.hazmat.backends import default_backend
from cryptography.exceptions import InvalidSignature
def sign(alg, contents, key=None):
print('Computing signature for alg {}'.format(alg))
# TODO move compute signature None here from attack_none
if key is not None and isinstance(key, str):
key = utils.force_bytes(key)
if contents is not None:
contents = utils.force_bytes(contents)
if alg.lower() == 'none':
return b''
if alg == "HS256":
return utils.base64url_encode(hmac.new(key, contents, hashlib.sha256).digest())
if alg == "HS384":
return utils.base64url_encode(hmac.new(key, contents, hashlib.sha384).digest())
if alg == "HS512":
return utils.base64url_encode(hmac.new(key, contents, hashlib.sha512).digest())
if alg == "RS256":
rsa_pk: RSAPrivateKey = key
return utils.base64url_encode(rsa_pk.sign(data=contents, padding=padding.PKCS1v15(), algorithm=hashes.SHA256()))
if alg == "RS384":
rsa_pk: RSAPrivateKey = key
return utils.base64url_encode(rsa_pk.sign(contents, padding.PKCS1v15(), hashes.SHA384()))
if alg == "RS512":
rsa_pk: RSAPrivateKey = key
return utils.base64url_encode(rsa_pk.sign(contents, padding.PKCS1v15(), hashes.SHA512()))
return utils.force_bytes('N/A')
def verify(alg, contents, key, sig):
if key is not None and isinstance(key, str):
key = utils.force_bytes(key)
test_sig = ""
if alg == "HS256":
test_sig = utils.base64url_encode(hmac.new(key, contents, hashlib.sha256).digest())
elif alg == "HS384":
test_sig = utils.base64url_encode(hmac.new(key, contents, hashlib.sha384).digest())
elif alg == "HS512":
test_sig = utils.base64url_encode(hmac.new(key, contents, hashlib.sha512).digest())
elif alg == "RS256":
rsa_pk: RSAPublicKey = key
rsa_pk.verify(signature=sig, data=contents, padding=padding.PKCS1v15(), algorithm=hashes.SHA256())
return True
elif alg == "RS384":
rsa_pk: RSAPublicKey = key
rsa_pk.verify(signature=sig, data=contents, padding=padding.PKCS1v15(), algorithm=hashes.SHA384())
return True
elif alg == "RS512":
rsa_pk: RSAPublicKey = key
rsa_pk.verify(signature=sig, data=contents, padding=padding.PKCS1v15(), algorithm=hashes.SHA512())
return True
else:
print("Unknown algorithm {}".format(alg))
verified = False
if test_sig == sig:
verified = True
if len(key) > 16:
print("Signature verified using key {}...".format(key[0:16]))
else:
print("Signature verified using key {}...".format(key))
else:
if len(key) > 16:
print("WARN Signature verification fail using key {}...".format(key[0:16]))
else:
print("WARN Signature verification fail using key {}...".format(key))
return verified