Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jvdsn
GitHub Repository: jvdsn/crypto-attacks
Path: blob/master/test/test_cbc.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
10
path = os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__))))
11
if sys.path[1] != path:
12
sys.path.insert(1, path)
13
14
from attacks.cbc import bit_flipping
15
from attacks.cbc import iv_recovery
16
from attacks.cbc import padding_oracle
17
18
19
class TestCBC(TestCase):
20
def _encrypt(self, key, p):
21
iv = randbytes(16)
22
cipher = AES.new(key, mode=AES.MODE_CBC, iv=iv)
23
c = cipher.encrypt(p)
24
return iv, c
25
26
def _decrypt(self, key, iv, c):
27
cipher = AES.new(key, mode=AES.MODE_CBC, iv=iv)
28
p = cipher.decrypt(c)
29
return p
30
31
def _valid_padding(self, key, iv, c):
32
try:
33
unpad(self._decrypt(key, iv, c), 16)
34
return True
35
except ValueError:
36
return False
37
38
def test_bit_flipping(self):
39
key = randbytes(16)
40
p = randbytes(32)
41
p_ = randbytes(16)
42
iv, c = self._encrypt(key, p)
43
44
iv_, c_ = bit_flipping.attack(iv, c, 0, p[0:len(p_)], p_)
45
p__ = self._decrypt(key, iv_, c_)
46
self.assertEqual(p_, p__[0:len(p_)])
47
48
iv_, c_ = bit_flipping.attack(iv, c, 16, p[16:16 + len(p_)], p_)
49
p__ = self._decrypt(key, iv_, c_)
50
self.assertEqual(p_, p__[16:16 + len(p_)])
51
52
def test_iv_recovery(self):
53
key = randbytes(16)
54
iv = randbytes(16)
55
iv_ = iv_recovery.attack(lambda c: self._decrypt(key, iv, c))
56
self.assertEqual(iv, iv_)
57
58
def test_padding_oracle(self):
59
key = randbytes(16)
60
for i in range(16):
61
p = pad(randbytes(i + 1), 16)
62
iv, c = self._encrypt(key, p)
63
p_ = padding_oracle.attack(lambda iv, c: self._valid_padding(key, iv, c), iv, c)
64
self.assertEqual(p, p_)
65
66