Commit 3c29cb5e authored by Markus Esmann's avatar Markus Esmann

implementation forbidden-attack

parent fe20648d
import cv2 as cv
import Server.server as server
def image_xor(server, image_left_path, image_right_path, out_path):
def image_xor(server, image1_path, image2_path, out_path):
"""
Verknüpfung von zwei verschlüsselten Bildern mithilfe der XOR-Operation
und anschließender Speicherung.
Parameters:
server (Server_Base) : Server zur Verschlüsselung der Bilder
image_left_path (string): Pfad des ersten Bildes
image_right_path (string): Pfad des zweiten Bildes
image1_path (string): Pfad des ersten Bildes
image2_path (string): Pfad des zweiten Bildes
out_path (string): Ausgabepfad
Returns:
bool: Angabe, ob die Speicherung des kombinierten Bildes erfolgreich war
"""
image_left_cipher = server.get_image(image_left_path)[0]
image_right_cipher = server.get_image(image_right_path)[0]
image_xor = cv.bitwise_xor(image_left_cipher, image_right_cipher, mask=None)
image1_cipher = server.get_image(image1_path)[0]
image2_cipher = server.get_image(image2_path)[0]
image_xor = cv.bitwise_xor(image1_cipher, image2_cipher, mask=None)
return cv.imwrite(out_path, image_xor)
import struct
from sage.all import *
from Crypto.Util.number import long_to_bytes as lb
from Crypto.Util.number import bytes_to_long as bl
from binascii import unhexlify, hexlify
#Initialisierung der Variablen und endlichen Körper aus dem mathematischen Modul Sage
var("x")
F, a = GF(2**128, name = "a", modulus = x**128 + x**7 + x**2 + x + 1).objgen()
R, x = PolynomialRing(F, name = "x").objgen()
def bytes_to_polynomial(block):
"""
Konvertierung der Bytedarstellung (Koeffizienten des Polynoms) in das zugehörige Polynom
Parameters:
block (bytes): Bytedarstellung des Polynoms
Returns:
(Sage->Polynomial): Polynom
"""
poly = 0
bin_block = bin(bl(block))[2 :].zfill(128)
for index in range(len(bin_block)):
poly += a**index * int(bin_block[index])
return poly
def polynomial_to_bytes(poly):
"""
Konvertierung eines Polynoms in die Bytedarstellung (Koeeffizienten des Polynoms)
Parameters:
poly (Sage->Polynomial): Polynom
Returns:
(bytes): Bytedarstellung des Polynoms
"""
bin_block = bin(poly.integer_representation())[2:].zfill(128)[::-1]
block = lb(int(bin_block, 2))
return block
def split_blocks(cipher):
"""
Aufteilung eines Chiffrats in Blöcke mit einer Größe von 16 Byte beziehungsweise 128 Bit.
Parameters:
cipher (byte): Chiffrat
Returns:
(byte[]): Chiffratblöcke (jeweils 128 Bit)
"""
blocks_128 = [cipher[index: index + 16] for index in range(0, len(cipher), 16)]
return blocks_128
def create_ghash_polynom(cipher_blocks, auth_tag, cipher_length):
"""
Erstellung eines GHASH-Polynoms auf Basis der Chiffratblöcke (jeweils 128 Bit) und dem
Autentisierungstag (128 Bit). Hierbei wird für jeden Block das Polynom des endlichen Körpers
GF(2^128) erstellt und zum GHASH-Polynom zusammengefügt.
Parameters:
cipher_blocks (byte[]): Chiffratblöcke (jeweils 128 Bit)
auth_tag (byte): Autehntisierungstag
cipher_length (int): Bitlänge des Chiffrats
Returns:
(Sage->Polynomial): GHASH-Polynom
"""
cipher_p = [bytes_to_polynomial(cipher_blocks[index]) for index in range(len(cipher_blocks))]
auth_tag_p = bytes_to_polynomial(auth_tag)
length_p = bytes_to_polynomial(struct.pack(">i", cipher_length * 8))
ghash_p = (length_p * x) + auth_tag_p
exponent = len(cipher_p) + 1
for index in range(len(cipher_p)):
ghash_p += (cipher_p[index] * x**exponent)
exponent -= 1
return ghash_p
def forbidden_attack(cipher1, auth_tag1, cipher2, auth_tag2):
"""
Implementierung des Forbidden-Attacks auf Basis von zwei Chiffraten und den zugehörigen
Authentifizierungstags. Zur Vereinfachung wurde hierbei auf eine Berücksichtigung der
assoziierten Daten verzichtet.
Parameters:
cipher1 (bytes): erstes Chiffrat
auth_tag1 (bytes): erster Authentisierungstag
cipher2 (bytes): zweites Chiffrat
auth_tag2 (bytes): zweiter Authentisierungstag
Returns:
bytes[] : Mögliche Kandidaten für den Autentisierungsschlüssel
"""
if not(isinstance(cipher1, bytes) and isinstance(auth_tag1, bytes) and isinstance(cipher2, bytes) and isinstance(auth_tag2, bytes)):
raise TypeError("Cipher and Auth-Tag must be bytes")
if cipher1 == cipher2:
raise ValueError("The ciphers must be different")
cipher1_blocks = split_blocks(cipher1)
cipher2_blocks = split_blocks(cipher2)
ghash1_p = create_ghash_polynom(cipher1_blocks, auth_tag1, len(cipher1))
ghash2_p = create_ghash_polynom(cipher2_blocks, auth_tag2, len(cipher2))
ghash_roots = (ghash1_p + ghash2_p).roots()
auth_keys = [polynomial_to_bytes(H).hex() for H, _ in ghash_roots]
return auth_keys
import os
from Crypto.Cipher import AES
import Server.server as server
import Tools.decryption as decryption
import Tools.forbidden_attack as fa
import Tools.decryption as decryption
if __name__ == "__main__":
def execute_forbidden_attack(cipher1, auth_tag1, cipher2, auth_tag2, key):
"""
Routine zur Durchführung des Forbidden-Attacks auf Basis von zwei Chiffraten und den
zugehörigen Authentisierungstags. Hierbei wird zunächst der Authentisierungsschlüssel
mithilfe des symmetrischen Schlüssles bestimmt und anschließend mit den im Angriff berechneten
Kandidaten verglichen.
Parameters:
cipher1 (bytes): erstes Chiffrat
auth_tag1 (bytes): erster Authentisierungstag
cipher2 (bytes): zweites Chiffrat
auth_tag2 (bytes): zweiter Authentisierungstag
key (bytes): symetrischer Schlüssel
"""
aes = AES.new(key, AES.MODE_ECB)
auth_key = aes.encrypt(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
print("\nVerwendeter Authentifizierungsschlüssel:\n\n\t", auth_key.hex())
fa_auth_keys = fa.forbidden_attack(cipher1, auth_tag1, cipher2, auth_tag2)
print("\nMögliche Kandidaten:\n")
for H in fa_auth_keys:
print("\t", H)
print()
def main():
"""
Hauptroutine dieses Systems zur Initialisierung des Mock-Servers und zum Start/Parametrisierung
der einzelnen Tools.
"""
key = os.urandom(32)
server = server.GCMServer_Nonce_Reuse(key)
#1. Visualisierung der Entschlüsselung bei einer GCM Nonce Reuse
#1.) Visualisierung der Entschlüsselung bei einer GCM Nonce Reuse
decryption.image_xor(server, r'Data\GCM.png', r'Data\Kryptografie.png', r'Data\XOR_Result.png')
#2.) Berechnung des Authentisierungsschlüssels mithilfe des Forbidden-Attack (hier: ohne assoziierte Daten)
cipher1, auth_tag1 = server.get_text_message()
cipher2, auth_tag2 = server.get_text_message()
execute_forbidden_attack(cipher1, auth_tag1, cipher2, auth_tag2, key)
if __name__ == "__main__":
main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment