Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ic:laboratoare:05 [2020/10/28 01:36]
acosmin.maria
ic:laboratoare:05 [2020/11/04 14:00] (current)
philip.dumitru [Exercise 3 (5p)]
Line 1: Line 1:
 ===== Laboratorul 05 - DES ===== ===== Laboratorul 05 - DES =====
- 
  
 In this lab we'll do some exercises with DES and some of its variants, as we discussed in the last lecture [[https://​drive.google.com/​file/​d/​1Fjybv6k5QudRB1bkAi5shVUGlUyTO_0U/​view|here]]. In this lab we'll do some exercises with DES and some of its variants, as we discussed in the last lecture [[https://​drive.google.com/​file/​d/​1Fjybv6k5QudRB1bkAi5shVUGlUyTO_0U/​view|here]].
 +
 +<file python utils.py>​
 +import base64
 +
 +# CONVERSION FUNCTIONS
 +def _chunks(string,​ chunk_size):​
 +    for i in range(0, len(string),​ chunk_size):​
 +        yield string[i:​i+chunk_size]
 +
 +def byte_2_bin(bval):​
 +    return bin(bval)[2:​].zfill(8)
 +
 +def _hex(x):
 +    return format(x, '​02x'​)
 +
 +def hex_2_bin(data):​
 +    return ''​.join(f'​{int(x,​ 16):​08b}'​ for x in _chunks(data,​ 2))
 +
 +def str_2_bin(data):​
 +    return ''​.join(f'​{ord(c):​08b}'​ for c in data)
 +
 +def bin_2_hex(data):​
 +    return ''​.join(f'​{int(b,​ 2):​02x}'​ for b in _chunks(data,​ 8))
 +
 +def str_2_hex(data):​
 +    return ''​.join(f'​{ord(c):​02x}'​ for c in data)
 +
 +def bin_2_str(data):​
 +    return ''​.join(chr(int(b,​ 2)) for b in _chunks(data,​ 8))
 +
 +def hex_2_str(data):​
 +    return ''​.join(chr(int(x,​ 16)) for x in _chunks(data,​ 2))
 +
 +# XOR FUNCTIONS
 +def strxor(a, b):  # xor two strings, trims the longer input
 +    return ''​.join(chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b))
 +
 +def bitxor(a, b):  # xor two bit-strings,​ trims the longer input
 +    return ''​.join(str(int(x) ^ int(y)) for (x, y) in zip(a, b))
 +
 +def hexxor(a, b):  # xor two hex-strings,​ trims the longer input
 +    return ''​.join(_hex(int(x,​ 16) ^ int(y, 16)) for (x, y) in zip(_chunks(a,​ 2), _chunks(b, 2)))
 +
 +# BASE64 FUNCTIONS
 +def b64decode(data):​
 +    return bytes_to_string(base64.b64decode(string_to_bytes(data)))
 +
 +def b64encode(data):​
 +    return bytes_to_string(base64.b64encode(string_to_bytes(data)))
 +
 +# PYTHON3 '​BYTES'​ FUNCTIONS
 +def bytes_to_string(bytes_data):​
 +    return bytes_data.decode() ​ # default utf-8
 +
 +def string_to_bytes(string_data):​
 +    return string_data.encode() ​ # default utf-8
 +    ​
 +# THIS ONE IS NEW
 +def hex_2_bytes(hex_data):​
 +    return bytes.fromhex(hex_data) ​ # default utf-8
 +</​file>​
  
 ==== Exercise 1 (2p) ==== ==== Exercise 1 (2p) ====
Line 26: Line 86:
 === A. Install the pycrypto library === === A. Install the pycrypto library ===
  
-See https://​pypi.python.org/​pypi/​pycrypto.+<​hidden>​this is outdated: ​https://​pypi.python.org/​pypi/​pycrypto.</​hidden>​ 
 +See https://​pypi.org/​project/​pycryptodome/​ 
  
 === B. Implement 2DES === === B. Implement 2DES ===
Line 75: Line 137:
 Your task is now to find the full keys k1 and k2 by applying the meet-in-the-middle attack over 2DES. Your task is now to find the full keys k1 and k2 by applying the meet-in-the-middle attack over 2DES.
  
-To build a table, ​recommend using a list of tuples, where you add new (key,enc) pairs as follows:+To build a table, ​we recommend using a list of tuples, where you add new (key,enc) pairs as follows:
 <​code>​ <​code>​
 tb = [] tb = []
-tb.append(('​keyval',​ 'encva'))+tb.append(('​keyval',​ 'encval'))
 </​code>​ </​code>​
  
Line 96: Line 158:
  
 <code python desmitm.py>​ <code python desmitm.py>​
-import ​sys +from utils import ​*
-import random +
-import string+
 from operator import itemgetter from operator import itemgetter
-import time 
 import bisect import bisect
 from Crypto.Cipher import DES from Crypto.Cipher import DES
- 
-def strxor(a, b): # xor two strings (trims the longer input) 
-  return ""​.join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b)]) 
- 
-def hexxor(a, b): # xor two hex strings (trims the longer input) 
-  ha = a.decode('​hex'​) 
-  hb = b.decode('​hex'​) 
-  return ""​.join([chr(ord(x) ^ ord(y)).encode('​hex'​) for (x, y) in zip(ha, hb)]) 
- 
-def bitxor(a, b): # xor two bit strings (trims the longer input) 
-  return ""​.join([str(int(x)^int(y)) for (x, y) in zip(a, b)]) 
- 
-def str2bin(ss):​ 
-  """​ 
-    Transform a string (e.g. '​Hello'​) into a string of bits 
-  """​ 
-  bs = ''​ 
-  for c in ss: 
-    bs = bs + bin(ord(c))[2:​].zfill(8) 
-  return bs 
- 
-def str2int(ss):​ 
-  """​ 
-    Transform a string (e.g. '​Hello'​) into a (long) integer by converting 
-    first to a bistream 
-  """​ 
-  bs = str2bin(ss) 
-  li = int(bs, 2) 
-  return li 
- 
-def hex2bin(hs):​ 
-  """​ 
-    Transform a hex string (e.g. '​a2'​) into a string of bits (e.g.10100010) 
-  """​ 
-  bs = ''​ 
-  for c in hs: 
-    bs = bs + bin(int(c,​16))[2:​].zfill(4) 
-  return bs 
- 
-def bin2hex(bs):​ 
-  """​ 
-    Transform a bit string into a hex string 
-  """​ 
-  bv = int(bs,2) 
-  return int2hexstring(bv) 
- 
-def byte2bin(bval):​ 
-  """​ 
-    Transform a byte (8-bit) value into a bitstring 
-  """​ 
-  return bin(bval)[2:​].zfill(8) 
- 
-def int2hexstring(bval):​ 
-  """​ 
-    Transform an int value into a hexstring (even number of characters) 
-  """​ 
-  hs = hex(bval)[2:​] 
-  lh = len(hs) 
-  return hs.zfill(lh + lh%2) 
  
 def get_index(a,​ x): def get_index(a,​ x):
-  'Locate the leftmost value exactly equal to x in list a' +    """​Locate the leftmost value exactly equal to x in list a"""​ 
-  i = bisect.bisect_left(a,​ x) +    i = bisect.bisect_left(a,​ x) 
-  if i != len(a) and a[i] == x: +    if i != len(a) and a[i] == x: 
-    return i +        return i 
-  else: +    else: 
-    return -1+        return -1
  
 def des_enc(k, m): def des_enc(k, m):
-  ​"""​ +    ​"""​ 
-  Encrypt a message m with a key k using DES as follows: +    Encrypt a message m with a key k using DES as follows: 
-  c = DES(k, m)+    c = DES(k, m)
  
-  ​Args: +    ​Args: 
-    m should be a bytestring (i.e. a sequence of characters such as '​Hello'​ or '​\x02\x04'​) +        m should be a bytestring (i.e. a sequence of characters such as '​Hello'​ or '​\x02\x04'​) 
-    k should be a bytestring of length exactly 8 bytes.+        k should be a bytestring of length exactly 8 bytes.
  
-  ​Note that for DES the key is given as 8 bytes, where the last bit of +    ​Note that for DES the key is given as 8 bytes, where the last bit of 
-  each byte is just a parity bit, giving the actual key of 56 bits, as expected for DES. +    each byte is just a parity bit, giving the actual key of 56 bits, as expected for DES. 
-  The parity bits are ignored.+    The parity bits are ignored.
  
-  ​Return: +    ​Return: 
-    The bytestring ciphertext c +        The bytestring ciphertext c 
-  """​ +    """​ 
-  d = DES.new(k) +    d = DES.new(k, DES.MODE_ECB
-  c = d.encrypt(m) +    c = d.encrypt(m) 
- +    return c
-  ​return c+
  
 def des_dec(k, c): def des_dec(k, c):
-  ​"""​ +    ​"""​ 
-  Decrypt a message c with a key k using DES as follows: +    Decrypt a message c with a key k using DES as follows: 
-  m = DES(k, c)+    m = DES(k, c)
  
-  ​Args: +    ​Args: 
-    c should be a bytestring (i.e. a sequence of characters such as '​Hello'​ or '​\x02\x04'​) +        c should be a bytestring (i.e. a sequence of characters such as '​Hello'​ or '​\x02\x04'​) 
-    k should be a bytestring of length exactly 8 bytes.+        k should be a bytestring of length exactly 8 bytes.
  
-  ​Note that for DES the key is given as 8 bytes, where the last bit of +    ​Note that for DES the key is given as 8 bytes, where the last bit of 
-  each byte is just a parity bit, giving the actual key of 56 bits, as expected for DES. +    each byte is just a parity bit, giving the actual key of 56 bits, as expected for DES. 
-  The parity bits are ignored.+    The parity bits are ignored.
  
-  ​Return: +    ​Return: 
-    The bytestring plaintext m +        The bytestring plaintext m 
-  """​ +    """​ 
-  d = DES.new(k) +    d = DES.new(k, DES.MODE_ECB
-  m = d.decrypt(c) +    m = d.decrypt(c) 
- +    return m
-  ​return m+
   ​   ​
 def main(): def main():
 +    # Exercitiu pentru test des2_enc
 +    key1 = '​Smerenie'​
 +    key2 = '​Dragoste'​
 +    m1_given = '​Fericiti cei saraci cu duhul, ca'
 +    c1 = '​cda98e4b247612e5b088a803b4277710f106beccf3d020ffcc577ddd889e2f32'​
 +    # TODO: implement des2_enc and des2_dec
 +    m1 = des2_dec(key1,​ key2, hex_2_str(c1))
  
-  # Exercitiu pentru test des2_enc +    print('​ciphertext:​ ' + c1) 
-  key1 = '​Smerenie'​ +    print('​plaintext:​ ' + m1) 
-  key2 = '​Dragoste'​ +    print('​plaintext in hexa: ' + str_2_hex(m1)
-  m1_given = '​Fericiti cei saraci cu duhul, ca' +     
-  c1 = '​cda98e4b247612e5b088a803b4277710f106beccf3d020ffcc577ddd889e2f32'​ +    # TODO: run meet-in-the-middle attack for the following plaintext/​ciphertext 
-  # TODO: implement des2_enc and des2_dec +    m1 = '​Pocainta'​ 
-  m1 = des2_dec(key1, key2, c1.decode('​hex'​)) +    c1 = '​9f98dbd6fe5f785d'​ # in hex string 
- +    m2 = '​Iertarea'​ 
-  print '​ciphertext:​ ' + c1 +    c2 = '​6e266642ef3069c2'​
-  print '​plaintext:​ ' + m1 +
-  print '​plaintext in hexa: ' + m1.encode('​hex'​+
- +
-  # TODO: run meet-in-the-middle attack for the following plaintext/​ciphertext +
-  m1 = '​Pocainta'​ +
-  c1 = '​9f98dbd6fe5f785d'​ # in hex string +
-  m2 = '​Iertarea'​ +
-  c2 = '​6e266642ef3069c2'​+
   ​   ​
-  ​# Note: you only need to search for the first 2 bytes of the each key: +    ​# Note: you only need to search for the first 2 bytes of the each key: 
-  k1 = '??​oIkvH5'​ +    k1 = '??​oIkvH5'​ 
-  k2 = '??​GK4EoU'​ +    k2 = '??​GK4EoU'​
- +
  
 if __name__ == "​__main__":​ if __name__ == "​__main__":​
-  ​main()+    ​main()
 </​code>​ </​code>​
  
ic/laboratoare/05.1603841783.txt.gz · Last modified: 2020/10/28 01:36 by acosmin.maria
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0