Repository navigation
Expand file tree
/
Copy pathverify.py
More file actions
86 lines (78 loc) · 2.23 KB
/
Copy pathverify.py
File metadata and controls
86 lines (78 loc) · 2.23 KB
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
86
"""
Verify.py:
Validates bonds to determine if they're kosher
"""
import base64
import Crypto.Util.number as CryptoNumber
import Crypto.Hash.SHA512 as SHA512
from global_storage import CryptoVars
def verify(bond):
"""
Verify that we have received a valid bond.
BOND = m^d, m = OAEP(PREFIX || Hash(n, x) || x).
"""
# Make sure the bond holds a number
try:
bond = longDecode(bond)
except Exception:
print 'Not a valid bond: value encoding'
return False
# BOND^e = m^d^e = m
msg = longToBytes(encrypt(bond))
# Since OAEP is all-or-nothing, we need to restore the leading zero bytes
msg = msg.rjust(CryptoVars.OAEP_cipher_len, chr(0))
# Try to decrypt OAEP format --> (PREFIX || Hash(h, x) || x)
try:
msg = deOAEP(msg)
except ValueError:
print 'Not a valid bond: OAEP failure'
return False
# Check for PREFIX
if not msg.startswith(CryptoVars.msg_prefix):
print 'Not a valid bond: msg_prefix failure'
return False
# Extract h = Hash(n, x) and x
msg = msg[len(CryptoVars.msg_prefix):]
h = msg[:-CryptoVars.x_len]
x = msg[-CryptoVars.x_len:]
# Check for x's prefix
if not x.startswith(CryptoVars.x_prefix):
print 'Not a valid bond: x_prefix failure'
return False
# Make sure that the hash is in fact Hash(n, x)
if h != hash(longToBytes(CryptoVars.n), x):
print 'Not a valid bond: hash failure'
return False
# Huzzah! It's valid!
print 'Success! Valid bond!'
return True
def longDecode(s):
"""
Decodes a base64 string (formed by longEncode) into a long
"""
return long(base64.b64decode(s), 16)
def encrypt(s):
"""
Wrapper around the encryption method used by Crypto.PublicKey.RSA._RSAobj
"""
# (the second argument is ignored, according to PyCrypto docs)
return CryptoVars.key.encrypt(s, 0)[0]
def longToBytes(n):
"""
Wrapper around the long-->bytestring method in Crypto.Util.number
"""
return CryptoNumber.long_to_bytes(n)
def deOAEP(s):
"""
Decrypt a string using OAEP and the OAEP cipher stored above. Note that this
does NOT use the main RSA encryption used for token and bond generation.
"""
return CryptoVars.OAEP_cipher.decrypt(s)
def hash(*args):
"""
Update a new SHA512 hash with one argument at a time, and return that hash.
"""
h = SHA512.new()
for arg in args:
h.update(arg)
return h.digest()