Криптография/Блочные шифры. Атаки на блочные шифры: различия между версиями

Материал из SecSem Wiki
Перейти к навигации Перейти к поиску
(Новая страница: «'''Ciphertexts''' <pre> xored_with_onebyte_key = b'%\r\r\x06B\x0e\x17\x01\tNB\n\x03\x14\x07B\x04\x17\x0c' xored_with_multibyte_key = b"\x07\x0b\r\x1c\x00I\x04\x…»)
 
Строка 1: Строка 1:
'''Ciphertexts'''
+
===Ссылки===
 +
* [https://drive.google.com/file/d/1RURDiTlyEmqzaHZKUOdueVzYWL28G_oU/view?usp=sharing презентация "Блочные шифры"]
 +
* [https://youtu.be/3-m-RQBpHZo видео "Блочные шифры"]
 +
 
 +
====Ciphertexts====
  
 
<pre>
 
<pre>
Строка 12: Строка 16:
 
                           b"\x08\x0c\x0b\x06 C\x0e\x1c\n\x04E\x006\x02\x0c\x07\x0b\x0eE\x0b<\x16\x1aN\x03\x00\t\x17 M"
 
                           b"\x08\x0c\x0b\x06 C\x0e\x1c\n\x04E\x006\x02\x0c\x07\x0b\x0eE\x0b<\x16\x1aN\x03\x00\t\x17 M"
  
 +
</pre>
 +
 +
 +
=== Задание 1===
 +
====Скрипт:====
 +
<syntaxhighlight lang="python">
 +
one = b'%\r\r\x06B\x0e\x17\x01\tNB\n\x03\x14\x07B\x04\x17\x0c'
 +
all_symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ, !?.()[]{}*-'
 +
for key in range(1, 256):
 +
    output = ''
 +
    for i in range(len(one)):
 +
        output = output + chr(one[i]^key)
 +
        if chr(one[i]^key) not in all_symbols:
 +
            output = ''
 +
            break
 +
    if len(output) > 0:
 +
        print('key = ', chr(key), ' output = ', output)
 +
</syntaxhighlight >
 +
 +
Вывод:
 +
<pre>
 +
key =  b  output =  Good luck, have fun
 +
key =  o  output =  Jbbi-axnf!-el{h-kxc
 +
</pre>
 +
 +
 +
=== Задание 2===
 +
 +
====Скрипт 1====
 +
Определяет длину ключа.
 +
<syntaxhighlight lang="python">
 +
xored_with_multibyte_key = b"\x07\x0b\r\x1c\x00I\x04\x006C\x1c\x19\nI\x0e\x1b=\x07\x1bN\n\x0fE\x11!\x1a" \
 +
                          b"\x18\x1a\n\x0e\x17\x13#\x0b\x11N\x0c\x07E\x06;\n\x1bN\x12\x06\x17\x1e7YH\r\x17" \
 +
                          b"\x10\x15\x06<\x04\x1a\x0f\x15\x01\x1cR'\x0b\t\x1aE\x1e\x0c\x1e?C\x1b\x1a\n\x19E" \
 +
                          b"\x0b<\x16\x1aN\x0e\x00\x01R \n\x1b\x1a\x00\x1bE\x14!\x0c\x05N\x17\x0c\x04\x16:\r\x0fN" \
 +
                          b"\x1c\x06\x10\x00s\x05\x01\x02\x00\x1aIR2\r\x0cN\x06\x1b\x1c\x02'\x0c\x0f\x1c\x04\x19\r" \
 +
                          b"\x0bs\x17\x00\x0f\x11I\x12\x1b?\x0fH\x1d\x11\x06\x15R>\x02\x02\x01\x17I\x02\x1d%\x06\x1a\x00" \
 +
                          b"\x08\x0c\x0b\x06 C\x0e\x1c\n\x04E\x006\x02\x0c\x07\x0b\x0eE\x0b<\x16\x1aN\x03\x00\t\x17 M"
 +
def weight(val):
 +
    res = 0
 +
    while val > 0:
 +
        res = res + val % 2;
 +
        val = val // 2
 +
    return res
 +
 +
print('Calculating Hamming distance')
 +
 +
for i in range(1, len(xored_with_multibyte_key)//2):
 +
    s  = 0
 +
    xored_with_multibyte_key_mov = xored_with_multibyte_key[i:]+xored_with_multibyte_key[:i]
 +
    for j in range(len(xored_with_multibyte_key)):
 +
        p = xored_with_multibyte_key[j] ^ xored_with_multibyte_key_mov[j]
 +
        s = s + weight(p)
 +
    if s/len(xored_with_multibyte_key) < 2.7:
 +
        print(i, ' ', s/len(xored_with_multibyte_key))
 +
</syntaxhighlight>
 +
 +
Вывод:
 +
<pre>
 +
Calculating Hamming distance
 +
8  2.536082474226804
 +
16  2.6597938144329896
 +
24  2.670103092783505
 +
64  2.6597938144329896
 +
72  2.6804123711340204
 +
</pre>
 +
 +
Выбираем длину ключа 8.
 +
 +
====Скрипт 2====
 +
Принимает на вход длину блока (разбивает строку на сеты и ломает каждый как однобайтовый xor-шифр):
 +
<syntaxhighlight lang="python">
 +
import sys
 +
xored_with_multibyte_key = b"\x07\x0b\r\x1c\x00I\x04\x006C\x1c\x19\nI\x0e\x1b=\x07\x1bN\n\x0fE\x11!\x1a" \
 +
                          b"\x18\x1a\n\x0e\x17\x13#\x0b\x11N\x0c\x07E\x06;\n\x1bN\x12\x06\x17\x1e7YH\r\x17" \
 +
                          b"\x10\x15\x06<\x04\x1a\x0f\x15\x01\x1cR'\x0b\t\x1aE\x1e\x0c\x1e?C\x1b\x1a\n\x19E" \
 +
                          b"\x0b<\x16\x1aN\x0e\x00\x01R \n\x1b\x1a\x00\x1bE\x14!\x0c\x05N\x17\x0c\x04\x16:\r\x0fN" \
 +
                          b"\x1c\x06\x10\x00s\x05\x01\x02\x00\x1aIR2\r\x0cN\x06\x1b\x1c\x02'\x0c\x0f\x1c\x04\x19\r" \
 +
                          b"\x0bs\x17\x00\x0f\x11I\x12\x1b?\x0fH\x1d\x11\x06\x15R>\x02\x02\x01\x17I\x02\x1d%\x06\x1a\x00" \
 +
                          b"\x08\x0c\x0b\x06 C\x0e\x1c\n\x04E\x006\x02\x0c\x07\x0b\x0eE\x0b<\x16\x1aN\x03\x00\t\x17 M"
 +
 +
sym = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ, !?.'
 +
 +
key_len = int(sys.argv[1])
 +
 +
def break_message(mes, k):
 +
    res = b""
 +
    for i in range(len(mes)//key_len):
 +
        res = res + mes[i*key_len+k:i*key_len+1+k]
 +
    return res
 +
 +
print('Finding possible keys\n')
 +
for t in range(key_len):
 +
    short_mes = break_message(xored_with_multibyte_key, t)
 +
    print('-'*25)
 +
    flag = 1
 +
    for i in range(1, 256):
 +
        output = ''
 +
        flag = 1
 +
        for j in range(len(short_mes)):
 +
            output = output + chr(i ^ short_mes[j])
 +
            if chr(i ^ short_mes[j]) not in sym and j < len(short_mes)-1:
 +
                flag = 0
 +
        if flag:
 +
            print(t+1, 'mini_key =', i, '->', chr(i), ' ', output)
 +
</syntaxhighlight>
 +
 +
Вывод:
 +
<pre>
 +
Finding possible keys
 +
 +
-------------------------
 +
1 mini_key = 83 -> S  Tenrphdotlosri at lmvseo
 +
-------------------------
 +
-------------------------
 +
3 mini_key = 104 -> h  etspys rasrsmgidgh jrfdr
 +
-------------------------
 +
4 mini_key = 110 -> n  rw t  catt t  l rasonri
 +
-------------------------
 +
5 mini_key = 101 -> e  eoooiwrp okeryecattrmonf
 +
-------------------------
 +
6 mini_key = 104 -> h  !!gfonxivqhsdnrsq!n!dlfh
 +
6 mini_key = 105 -> i    fgnoyhwpireosrp o emgi
 +
6 mini_key = 118 -> v  ??yxqpfwhovmzplmo?p?zrxv
 +
-------------------------
 +
7 mini_key = 101 -> e  ak r rpyi d au,yhwpgn  l
 +
-------------------------
 +
8 mini_key = 114 -> r  ricatlt ly fdr pyi otrye
 +
</pre>
 +
 +
====Скрипт 3====
 +
Принимает на вход ключ (если символ ключа - '*', то не преобразует соответствующий символ шифр-текста).
 +
<syntaxhighlight lang="python">
 +
import sys
 +
xored_with_multibyte_key = b"\x07\x0b\r\x1c\x00I\x04\x006C\x1c\x19\nI\x0e\x1b=\x07\x1bN\n\x0fE\x11!\x1a" \
 +
                          b"\x18\x1a\n\x0e\x17\x13#\x0b\x11N\x0c\x07E\x06;\n\x1bN\x12\x06\x17\x1e7YH\r\x17" \
 +
                          b"\x10\x15\x06<\x04\x1a\x0f\x15\x01\x1cR'\x0b\t\x1aE\x1e\x0c\x1e?C\x1b\x1a\n\x19E" \
 +
                          b"\x0b<\x16\x1aN\x0e\x00\x01R \n\x1b\x1a\x00\x1bE\x14!\x0c\x05N\x17\x0c\x04\x16:\r\x0fN" \
 +
                          b"\x1c\x06\x10\x00s\x05\x01\x02\x00\x1aIR2\r\x0cN\x06\x1b\x1c\x02'\x0c\x0f\x1c\x04\x19\r" \
 +
                          b"\x0bs\x17\x00\x0f\x11I\x12\x1b?\x0fH\x1d\x11\x06\x15R>\x02\x02\x01\x17I\x02\x1d%\x06\x1a\x00" \
 +
                          b"\x08\x0c\x0b\x06 C\x0e\x1c\n\x04E\x006\x02\x0c\x07\x0b\x0eE\x0b<\x16\x1aN\x03\x00\t\x17 M"
 +
 +
key = sys.argv[1]
 +
key_len = len(key)
 +
 +
output = ''
 +
for i in range(len(xored_with_multibyte_key)):
 +
    if key[i%key_len] == '*':
 +
        output = output + chr(xored_with_multibyte_key[i])
 +
    else:
 +
        output = output + chr(xored_with_multibyte_key[i] ^ ord(key[i%key_len]))
 +
 +
print(output)
 +
</syntaxhighlight >
 +
 +
Вывод для аргумента 'S*hneier'
 +
<pre>
 +
T
 +
ere areCtwo kins of cr�ptograp
 +
                              y in th
 +
s worldY cryptoraphy t
 +
                      at willCstop yor kid s
 +
ster fr
 +
d cryptiles, a
 +
      graphy hat wil stop mjor govrnmentsCfrom reding yor filesM
 +
</pre>
 +
 +
Второй символ ключа угадываем из идеи, что строка <code>willCstop</code> должно отобразиться в <code>will stop</code>, тогда он определяется как <code>chr(ord('C')^ord(' '))</code> и равен <code>c</code>. В итоге ключ равен <code>Schneier</code> а текст расшифровывается в
 +
 +
<pre>
 +
There are two kinds of cryptography in this world: cryptography that will stop your kid sister from reading your files, and cryptography that will stop major governments from reading your files.
 
</pre>
 
</pre>

Версия 17:22, 15 марта 2021

Ссылки

Ciphertexts

xored_with_onebyte_key = b'%\r\r\x06B\x0e\x17\x01\tNB\n\x03\x14\x07B\x04\x17\x0c'

xored_with_multibyte_key = b"\x07\x0b\r\x1c\x00I\x04\x006C\x1c\x19\nI\x0e\x1b=\x07\x1bN\n\x0fE\x11!\x1a" \
                           b"\x18\x1a\n\x0e\x17\x13#\x0b\x11N\x0c\x07E\x06;\n\x1bN\x12\x06\x17\x1e7YH\r\x17" \
                           b"\x10\x15\x06<\x04\x1a\x0f\x15\x01\x1cR'\x0b\t\x1aE\x1e\x0c\x1e?C\x1b\x1a\n\x19E" \
                           b"\x0b<\x16\x1aN\x0e\x00\x01R \n\x1b\x1a\x00\x1bE\x14!\x0c\x05N\x17\x0c\x04\x16:\r\x0fN" \
                           b"\x1c\x06\x10\x00s\x05\x01\x02\x00\x1aIR2\r\x0cN\x06\x1b\x1c\x02'\x0c\x0f\x1c\x04\x19\r" \
                           b"\x0bs\x17\x00\x0f\x11I\x12\x1b?\x0fH\x1d\x11\x06\x15R>\x02\x02\x01\x17I\x02\x1d%\x06\x1a\x00" \
                           b"\x08\x0c\x0b\x06 C\x0e\x1c\n\x04E\x006\x02\x0c\x07\x0b\x0eE\x0b<\x16\x1aN\x03\x00\t\x17 M"


Задание 1

Скрипт:

one = b'%\r\r\x06B\x0e\x17\x01\tNB\n\x03\x14\x07B\x04\x17\x0c'
all_symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ, !?.()[]{}*-'
for key in range(1, 256):
    output = ''
    for i in range(len(one)):
        output = output + chr(one[i]^key)
        if chr(one[i]^key) not in all_symbols:
            output = ''
            break
    if len(output) > 0:
        print('key = ', chr(key), ' output = ', output)

Вывод:

key =  b  output =  Good luck, have fun
key =  o  output =  Jbbi-axnf!-el{h-kxc


Задание 2

Скрипт 1

Определяет длину ключа.

xored_with_multibyte_key = b"\x07\x0b\r\x1c\x00I\x04\x006C\x1c\x19\nI\x0e\x1b=\x07\x1bN\n\x0fE\x11!\x1a" \
                           b"\x18\x1a\n\x0e\x17\x13#\x0b\x11N\x0c\x07E\x06;\n\x1bN\x12\x06\x17\x1e7YH\r\x17" \
                           b"\x10\x15\x06<\x04\x1a\x0f\x15\x01\x1cR'\x0b\t\x1aE\x1e\x0c\x1e?C\x1b\x1a\n\x19E" \
                           b"\x0b<\x16\x1aN\x0e\x00\x01R \n\x1b\x1a\x00\x1bE\x14!\x0c\x05N\x17\x0c\x04\x16:\r\x0fN" \
                           b"\x1c\x06\x10\x00s\x05\x01\x02\x00\x1aIR2\r\x0cN\x06\x1b\x1c\x02'\x0c\x0f\x1c\x04\x19\r" \
                           b"\x0bs\x17\x00\x0f\x11I\x12\x1b?\x0fH\x1d\x11\x06\x15R>\x02\x02\x01\x17I\x02\x1d%\x06\x1a\x00" \
                           b"\x08\x0c\x0b\x06 C\x0e\x1c\n\x04E\x006\x02\x0c\x07\x0b\x0eE\x0b<\x16\x1aN\x03\x00\t\x17 M"
def weight(val):
    res = 0
    while val > 0:
        res = res + val % 2;
        val = val // 2
    return res

print('Calculating Hamming distance')

for i in range(1, len(xored_with_multibyte_key)//2):
    s  = 0
    xored_with_multibyte_key_mov = xored_with_multibyte_key[i:]+xored_with_multibyte_key[:i]
    for j in range(len(xored_with_multibyte_key)):
        p = xored_with_multibyte_key[j] ^ xored_with_multibyte_key_mov[j]
        s = s + weight(p)
    if s/len(xored_with_multibyte_key) < 2.7:
        print(i, ' ', s/len(xored_with_multibyte_key))

Вывод:

Calculating Hamming distance
8   2.536082474226804
16   2.6597938144329896
24   2.670103092783505
64   2.6597938144329896
72   2.6804123711340204

Выбираем длину ключа 8.

Скрипт 2

Принимает на вход длину блока (разбивает строку на сеты и ломает каждый как однобайтовый xor-шифр):

import sys
xored_with_multibyte_key = b"\x07\x0b\r\x1c\x00I\x04\x006C\x1c\x19\nI\x0e\x1b=\x07\x1bN\n\x0fE\x11!\x1a" \
                           b"\x18\x1a\n\x0e\x17\x13#\x0b\x11N\x0c\x07E\x06;\n\x1bN\x12\x06\x17\x1e7YH\r\x17" \
                           b"\x10\x15\x06<\x04\x1a\x0f\x15\x01\x1cR'\x0b\t\x1aE\x1e\x0c\x1e?C\x1b\x1a\n\x19E" \
                           b"\x0b<\x16\x1aN\x0e\x00\x01R \n\x1b\x1a\x00\x1bE\x14!\x0c\x05N\x17\x0c\x04\x16:\r\x0fN" \
                           b"\x1c\x06\x10\x00s\x05\x01\x02\x00\x1aIR2\r\x0cN\x06\x1b\x1c\x02'\x0c\x0f\x1c\x04\x19\r" \
                           b"\x0bs\x17\x00\x0f\x11I\x12\x1b?\x0fH\x1d\x11\x06\x15R>\x02\x02\x01\x17I\x02\x1d%\x06\x1a\x00" \
                           b"\x08\x0c\x0b\x06 C\x0e\x1c\n\x04E\x006\x02\x0c\x07\x0b\x0eE\x0b<\x16\x1aN\x03\x00\t\x17 M"

sym = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ, !?.'

key_len = int(sys.argv[1])

def break_message(mes, k):
    res = b""
    for i in range(len(mes)//key_len):
        res = res + mes[i*key_len+k:i*key_len+1+k]
    return res

print('Finding possible keys\n')
for t in range(key_len):
    short_mes = break_message(xored_with_multibyte_key, t)
    print('-'*25)
    flag = 1
    for i in range(1, 256):
        output = ''
        flag = 1
        for j in range(len(short_mes)):
            output = output + chr(i ^ short_mes[j])
            if chr(i ^ short_mes[j]) not in sym and j < len(short_mes)-1:
                flag = 0
        if flag:
            print(t+1, 'mini_key =', i, '->', chr(i), ' ', output)

Вывод:

Finding possible keys

-------------------------
1 mini_key = 83 -> S   Tenrphdotlosri at lmvseo
-------------------------
-------------------------
3 mini_key = 104 -> h   etspys rasrsmgidgh jrfdr
-------------------------
4 mini_key = 110 -> n   rw t  catt t  l rasonri 
-------------------------
5 mini_key = 101 -> e   eoooiwrp okeryecattrmonf
-------------------------
6 mini_key = 104 -> h   !!gfonxivqhsdnrsq!n!dlfh
6 mini_key = 105 -> i     fgnoyhwpireosrp o emgi
6 mini_key = 118 -> v   ??yxqpfwhovmzplmo?p?zrxv
-------------------------
7 mini_key = 101 -> e   ak r rpyi d au,yhwpgn  l
-------------------------
8 mini_key = 114 -> r   ricatlt ly fdr pyi otrye

Скрипт 3

Принимает на вход ключ (если символ ключа - '*', то не преобразует соответствующий символ шифр-текста).

import sys
xored_with_multibyte_key = b"\x07\x0b\r\x1c\x00I\x04\x006C\x1c\x19\nI\x0e\x1b=\x07\x1bN\n\x0fE\x11!\x1a" \
                           b"\x18\x1a\n\x0e\x17\x13#\x0b\x11N\x0c\x07E\x06;\n\x1bN\x12\x06\x17\x1e7YH\r\x17" \
                           b"\x10\x15\x06<\x04\x1a\x0f\x15\x01\x1cR'\x0b\t\x1aE\x1e\x0c\x1e?C\x1b\x1a\n\x19E" \
                           b"\x0b<\x16\x1aN\x0e\x00\x01R \n\x1b\x1a\x00\x1bE\x14!\x0c\x05N\x17\x0c\x04\x16:\r\x0fN" \
                           b"\x1c\x06\x10\x00s\x05\x01\x02\x00\x1aIR2\r\x0cN\x06\x1b\x1c\x02'\x0c\x0f\x1c\x04\x19\r" \
                           b"\x0bs\x17\x00\x0f\x11I\x12\x1b?\x0fH\x1d\x11\x06\x15R>\x02\x02\x01\x17I\x02\x1d%\x06\x1a\x00" \
                           b"\x08\x0c\x0b\x06 C\x0e\x1c\n\x04E\x006\x02\x0c\x07\x0b\x0eE\x0b<\x16\x1aN\x03\x00\t\x17 M"

key = sys.argv[1]
key_len = len(key)

output = ''
for i in range(len(xored_with_multibyte_key)):
    if key[i%key_len] == '*':
        output = output + chr(xored_with_multibyte_key[i])
    else:
        output = output + chr(xored_with_multibyte_key[i] ^ ord(key[i%key_len]))

print(output)

Вывод для аргумента 'S*hneier'

T
 ere areCtwo kins of cr�ptograp
                               y in th
s worldY cryptoraphy t
                      at willCstop yor kid s
ster fr
d cryptiles, a
       graphy hat wil stop mjor govrnmentsCfrom reding yor filesM

Второй символ ключа угадываем из идеи, что строка willCstop должно отобразиться в will stop, тогда он определяется как chr(ord('C')^ord(' ')) и равен c. В итоге ключ равен Schneier а текст расшифровывается в

There are two kinds of cryptography in this world: cryptography that will stop your kid sister from reading your files, and cryptography that will stop major governments from reading your files.