Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jvdsn
GitHub Repository: jvdsn/crypto-attacks
Path: blob/master/test/test_ige.py
2587 views
1
import os
2
import sys
3
from random import randbytes
4
from unittest import TestCase
5
6
from Crypto.Cipher import AES
7
from Crypto.Util.Padding import pad
8
from Crypto.Util.Padding import unpad
9
from Crypto.Util.strxor import strxor
10
11
path = os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__))))
12
if sys.path[1] != path:
13
sys.path.insert(1, path)
14
15
from attacks.ige import padding_oracle
16
17
18
class TestIGE(TestCase):
19
def _encrypt(self, key, p):
20
p0 = randbytes(16)
21
c0 = randbytes(16)
22
cipher = AES.new(key, mode=AES.MODE_ECB)
23
24
p_last = p0
25
c_last = c0
26
c = bytearray()
27
for i in range(0, len(p), 16):
28
p_i = p[i:i + 16]
29
c_i = strxor(cipher.encrypt(strxor(p_i, c_last)), p_last)
30
p_last = p_i
31
c_last = c_i
32
c += c_i
33
34
return p0, c0, c
35
36
def _decrypt(self, key, p0, c0, c):
37
cipher = AES.new(key, mode=AES.MODE_ECB)
38
p_last = p0
39
c_last = c0
40
p = bytearray()
41
for i in range(0, len(c), 16):
42
c_i = c[i:i + 16]
43
p_i = strxor(cipher.decrypt(strxor(c_i, p_last)), c_last)
44
p_last = p_i
45
c_last = c_i
46
p += p_i
47
48
return p
49
50
def _valid_padding(self, key, p0, c0, c):
51
try:
52
unpad(self._decrypt(key, p0, c0, c), 16)
53
return True
54
except ValueError:
55
return False
56
57
def test_padding_oracle(self):
58
key = randbytes(16)
59
60
for i in range(16):
61
p = pad(randbytes(i + 1), 16)
62
p0, c0, c = self._encrypt(key, p)
63
p_ = padding_oracle.attack(lambda p0, c0, c: self._valid_padding(key, p0, c0, c), p0, c0, c)
64
self.assertEqual(p, p_)
65
66