Криптография/Блочные шифры. Атаки на блочные шифры: различия между версиями
Dzeni (обсуждение | вклад) (Новая страница: «'''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…») |
Dzeni (обсуждение | вклад) м (→Задание 2) |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 1: | Строка 1: | ||
− | + | ===Ссылки=== | |
+ | * [https://drive.google.com/file/d/1RURDiTlyEmqzaHZKUOdueVzYWL28G_oU/view?usp=sharing презентация "Блочные шифры"] | ||
+ | * [https://youtu.be/3-m-RQBpHZo видео "Блочные шифры"] | ||
+ | ====Ciphertexts==== | ||
+ | |||
+ | <syntaxhighlight lang="python"> | ||
+ | xored_with_onebyte_key = b"'\x1c\x1cS\x14\x1c\x1c\x17S\x07\x1cS\x11\x16S\x07\x01\x06\x16" | ||
+ | |||
+ | xored_with_multibyte_key = b'\x08T\x1f\x10\x1a\x10E\x1d.\x00R\x03\x0c\x05\x17]a2\x17\x04\x1bD\x0c\x00a\x00\x1a\x00I\t\x0c\x1d%Y\x19\x0c\x05'\ | ||
+ | b'\x08\x00\x01oT4\x00\x08\x16E\x1a2T\x06\r\x0cD\t\x1a5\x00\x1e\x00D\x00\x00\x125\x1cR\x11\x01\x05\x11S#\x06\x1b\x0b\x0e'\ | ||
+ | b'\x17E\x07.\x00\x13\tI\x0b\x07\x1f(\x00\x17\x17\x08\x10\x0c\x1c/ZR,I\x13\x0c\x1f-T\x14\x04\n\x01E\x1e8T\x14\x00\x08\x16K'\ | ||
+ | b'S\x08T\x05\x0c\x05\x08E\x03$\x06\x1f\x0c\x1dD\x0c\x07a\x00\x1dE\x19\x05\x16\x00a\x1b\x04\x00\x1bD\x08\x16a\x15\x1c\x01I'\ | ||
+ | b'\x10\r\x01.\x01\x15\rI\t\x00]a5\x1c\x01I\x13\r\x16/T\x1b\x11I\x0c\x04\x00a\x13\x1d\x0b\x0cD\x15\x122\x00^E D\x12\x1a-\x18R'\ | ||
+ | b'\x11\x1c\x16\x0bS5\x1c\x17E\x00\n\x0b\x163T\x17\x1c\x0cD\x11\x1ca\x07\x17\x00I\r\x11\x00a\x04\x13\x11\x01JE$)\x11\x00\x00I'\ | ||
+ | b'\x10\r\x16a\x12\x17\x04\x1bD\r\x122T\x15\n\x07\x01E\x07)\x11\x00\x00I\x13\x0c\x1f-T\x10\x00I\n\n\x07)\x1d\x1c\x02GD*\x1d-\rR,I\x13'\ | ||
+ | b'\x0c\x1f-T\x00\x00\x04\x05\x0c\x1do' | ||
+ | |||
+ | </syntaxhighlight > | ||
+ | |||
+ | === Задание 1=== | ||
+ | ====Скрипт:==== | ||
+ | <syntaxhighlight lang="python"> | ||
+ | symbl = "qwertyuiopasdfghjklzxcvbnm,./;'[]!? QWERTYUIOPASDFGHJKLZXCVBNM" | ||
+ | |||
+ | def xor_srting(str, key): | ||
+ | result = '' | ||
+ | for i in range(len(str)): | ||
+ | s = chr(str[i] ^ key) | ||
+ | if s not in symbl: | ||
+ | return False | ||
+ | else: | ||
+ | result += s | ||
+ | return result | ||
+ | |||
+ | |||
+ | for k in range(256): | ||
+ | p = xor_srting(xored_with_onebyte_key , k) | ||
+ | if p: | ||
+ | print('key ', k, 'str ', p) | ||
+ | </syntaxhighlight > | ||
+ | |||
+ | Вывод: | ||
+ | <pre> | ||
+ | key 114 str Unn!fnne!un!cd!ustd | ||
+ | key 115 str Too good to be true | ||
+ | </pre> | ||
+ | |||
+ | === Задание 2=== | ||
+ | |||
+ | ====Скрипт 1==== | ||
+ | Определяет длину ключа. | ||
+ | <syntaxhighlight lang="python"> | ||
+ | symbl = "qwertyuiopasdfghjklzxcvbnm,./;'[]!? QWERTYUIOPASDFGHJKLZXCVBNM" | ||
+ | |||
+ | def count_weight(num): | ||
+ | return bin(num).count('1') | ||
+ | |||
+ | def foo(str, key_len): | ||
+ | weight = 0 | ||
+ | tmp_str = str[key_len:] + str[:key_len] | ||
+ | for i in range(len(str)): | ||
+ | weight += count_weight(str[i] ^ tmp_str[i]) | ||
+ | return weight/len(str) | ||
+ | |||
+ | |||
+ | for i in range(2, len(c)//2): | ||
+ | #tmp_w = xor_srting(c, i) | ||
+ | tmp_w = foo(c, i) | ||
+ | if tmp_w < 2.7: | ||
+ | print(i, ' ', tmp_w) | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | Вывод: | ||
+ | <pre> | ||
+ | Calculating Hamming distance | ||
+ | 8 2.498360655737705 | ||
+ | 16 2.5311475409836066 | ||
+ | 24 2.6950819672131145 | ||
+ | 32 2.675409836065574 | ||
+ | </pre> | ||
+ | |||
+ | Выбираем длину ключа 8. | ||
+ | |||
+ | ====Скрипт 2==== | ||
+ | Принимает на вход длину блока (разбивает строку на сеты и ломает каждый как однобайтовый xor-шифр): | ||
+ | <syntaxhighlight lang="python"> | ||
+ | |||
+ | symbl = "qwertyuiopasdfghjklzxcvbnm,./;[]!? QWERTYUIOPASDFGHJKLZXCVBNM" | ||
+ | key_len = 8 | ||
+ | |||
+ | def xor_srting(str, key): | ||
+ | result = '' | ||
+ | for i in range(len(str)): | ||
+ | s = chr(str[i] ^ key) | ||
+ | if s in symbl: | ||
+ | result += s | ||
+ | else: | ||
+ | return False | ||
+ | #result += s | ||
+ | return result | ||
+ | |||
+ | def find_key(c): | ||
+ | for k in range(256): | ||
+ | p = xor_srting(c, k) | ||
+ | if p: | ||
+ | print('key:', chr(k), '| text:', p) | ||
+ | |||
+ | |||
+ | print('Finding possible keys\n') | ||
+ | |||
+ | for j in range(key_len): | ||
+ | short_c = b'' | ||
+ | for q in range(len(c)//key_len): | ||
+ | short_c += c[j + key_len*q].to_bytes(1, 'big') | ||
+ | find_key(short_c) | ||
+ | print('-'*25) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Вывод: | ||
<pre> | <pre> | ||
− | + | Finding possible keys | |
− | + | key: @ | text: Hn!!e/ruucnhomxHd!!!n!o!rmus!!i!rimimm | |
− | + | key: A | text: Io d.sttboinlyIe o n sltr h shlhll | |
− | + | ------------------------- | |
− | + | ------------------------- | |
− | + | key: r | text: m ehkFtl iae ffwmovngnio, eeearegrbn r | |
− | + | ------------------------- | |
− | + | key: e | text: ufaeiehetnlrIaeii edhdtn t yeteaoeegIe | |
+ | ------------------------- | ||
+ | ------------------------- | ||
+ | key: d | text: ta mlr dasotwerl a tmwh rn i.t ewn wa | ||
+ | ------------------------- | ||
+ | key: e | text: riie let bii . ismhehapwnntt hh ioOii | ||
+ | ------------------------- | ||
+ | key: s | text: n.snriia tlolm ptser.esai eosWeatltnln | ||
+ | ------------------------- | ||
+ | </pre> | ||
+ | ====Скрипт 3==== | ||
+ | Принимает на вход ключ (если символ ключа - '*', то не преобразует соответствующий символ шифр-текста). | ||
+ | <syntaxhighlight lang="python"> | ||
+ | symbl = "qwertyuiopasdfghjklzxcvbnm,./;[]!? QWERTYUIOPASDFGHJKLZXCVBNM" | ||
+ | key_len = 8 | ||
+ | key = b'**re*des' | ||
+ | |||
+ | res = '' | ||
+ | for i in range(len(c)): | ||
+ | if key[i % key_len] != b'*'[0]: | ||
+ | key_symbol = key[i % key_len] | ||
+ | else: | ||
+ | key_symbol = 0 | ||
+ | res += chr(c[i] ^ key_symbol) | ||
+ | |||
+ | print(res) | ||
+ | </syntaxhighlight > | ||
+ | |||
+ | Вывод для аргумента '**re*des' | ||
+ | <pre> | ||
+ | Tmu�t n. f | ||
+ | ar.a2easaheImin%YkileroTFr i2Tth | ||
+ | li5leDdea5 tat #ins t.alIobl(etio/Z IIwil-Tfa | ||
+ | e m8Tfr.Twil p$mi itao assaeeandIthr.ghIme.a5ndIwhe/TitIhasaon | ||
+ | pa2, wi- trn 5e nne3Tey | ||
+ | toaeeIitsaat. W IIwil-Treainooe t)reIwil-TbeInot)ngG On- | ||
+ | </pre> | ||
+ | |||
+ | Первый символ ключа выбирается из <code>A</code> и <code>@</code> по более осмысленному тексту при соответствующей подстановке. | ||
+ | |||
+ | Вывод для аргумента 'A*re*des' | ||
+ | <pre> | ||
+ | ITmu�t no f | ||
+ | ar. 2eas heImindYkiler.TFr isTth | ||
+ | litleDdeat tat bins toalIoblietionZ IIwillTfa | ||
+ | e myTfr. ITwil pemi it o ass ee ndIthroghIme. 5ndIwhenTitIhas on | ||
+ | pas, wil trn te nnerTey | ||
+ | to eeIits at. IIwillTreain.Tgoe threIwillTbeInothngG Onl | ||
+ | </pre> | ||
+ | |||
+ | Второй символ ключа угадываем из идеи, что строка <code>whenTit</code> должно отобразиться в <code>when it</code>, тогда он определяется как <code>chr(ord('T')^ord(' '))</code> и равен <code>t</code>. | ||
+ | Пятый символ ключа угадываем из идеи, что строка <code>itIhas</code> должно отобразиться в <code>itIhas</code>, тогда он определяется как <code>chr(ord('I')^ord(' '))</code> и равен <code>i</code>. | ||
+ | |||
+ | В итоге ключ равен <code>Atreides</code>а текст расшифровывается в | ||
+ | |||
+ | <pre> | ||
+ | I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. And when it has gone past, I will turn the inner eye to see its path. Where the fear has gone there will be nothing. Only I will remain. | ||
</pre> | </pre> |
Текущая версия на 11:23, 29 февраля 2024
Содержание
Ссылки
Ciphertexts
xored_with_onebyte_key = b"'\x1c\x1cS\x14\x1c\x1c\x17S\x07\x1cS\x11\x16S\x07\x01\x06\x16"
xored_with_multibyte_key = b'\x08T\x1f\x10\x1a\x10E\x1d.\x00R\x03\x0c\x05\x17]a2\x17\x04\x1bD\x0c\x00a\x00\x1a\x00I\t\x0c\x1d%Y\x19\x0c\x05'\
b'\x08\x00\x01oT4\x00\x08\x16E\x1a2T\x06\r\x0cD\t\x1a5\x00\x1e\x00D\x00\x00\x125\x1cR\x11\x01\x05\x11S#\x06\x1b\x0b\x0e'\
b'\x17E\x07.\x00\x13\tI\x0b\x07\x1f(\x00\x17\x17\x08\x10\x0c\x1c/ZR,I\x13\x0c\x1f-T\x14\x04\n\x01E\x1e8T\x14\x00\x08\x16K'\
b'S\x08T\x05\x0c\x05\x08E\x03$\x06\x1f\x0c\x1dD\x0c\x07a\x00\x1dE\x19\x05\x16\x00a\x1b\x04\x00\x1bD\x08\x16a\x15\x1c\x01I'\
b'\x10\r\x01.\x01\x15\rI\t\x00]a5\x1c\x01I\x13\r\x16/T\x1b\x11I\x0c\x04\x00a\x13\x1d\x0b\x0cD\x15\x122\x00^E D\x12\x1a-\x18R'\
b'\x11\x1c\x16\x0bS5\x1c\x17E\x00\n\x0b\x163T\x17\x1c\x0cD\x11\x1ca\x07\x17\x00I\r\x11\x00a\x04\x13\x11\x01JE$)\x11\x00\x00I'\
b'\x10\r\x16a\x12\x17\x04\x1bD\r\x122T\x15\n\x07\x01E\x07)\x11\x00\x00I\x13\x0c\x1f-T\x10\x00I\n\n\x07)\x1d\x1c\x02GD*\x1d-\rR,I\x13'\
b'\x0c\x1f-T\x00\x00\x04\x05\x0c\x1do'
Задание 1
Скрипт:
symbl = "qwertyuiopasdfghjklzxcvbnm,./;'[]!? QWERTYUIOPASDFGHJKLZXCVBNM"
def xor_srting(str, key):
result = ''
for i in range(len(str)):
s = chr(str[i] ^ key)
if s not in symbl:
return False
else:
result += s
return result
for k in range(256):
p = xor_srting(xored_with_onebyte_key , k)
if p:
print('key ', k, 'str ', p)
Вывод:
key 114 str Unn!fnne!un!cd!ustd key 115 str Too good to be true
Задание 2
Скрипт 1
Определяет длину ключа.
symbl = "qwertyuiopasdfghjklzxcvbnm,./;'[]!? QWERTYUIOPASDFGHJKLZXCVBNM"
def count_weight(num):
return bin(num).count('1')
def foo(str, key_len):
weight = 0
tmp_str = str[key_len:] + str[:key_len]
for i in range(len(str)):
weight += count_weight(str[i] ^ tmp_str[i])
return weight/len(str)
for i in range(2, len(c)//2):
#tmp_w = xor_srting(c, i)
tmp_w = foo(c, i)
if tmp_w < 2.7:
print(i, ' ', tmp_w)
Вывод:
Calculating Hamming distance 8 2.498360655737705 16 2.5311475409836066 24 2.6950819672131145 32 2.675409836065574
Выбираем длину ключа 8.
Скрипт 2
Принимает на вход длину блока (разбивает строку на сеты и ломает каждый как однобайтовый xor-шифр):
symbl = "qwertyuiopasdfghjklzxcvbnm,./;[]!? QWERTYUIOPASDFGHJKLZXCVBNM"
key_len = 8
def xor_srting(str, key):
result = ''
for i in range(len(str)):
s = chr(str[i] ^ key)
if s in symbl:
result += s
else:
return False
#result += s
return result
def find_key(c):
for k in range(256):
p = xor_srting(c, k)
if p:
print('key:', chr(k), '| text:', p)
print('Finding possible keys\n')
for j in range(key_len):
short_c = b''
for q in range(len(c)//key_len):
short_c += c[j + key_len*q].to_bytes(1, 'big')
find_key(short_c)
print('-'*25)
Вывод:
Finding possible keys key: @ | text: Hn!!e/ruucnhomxHd!!!n!o!rmus!!i!rimimm key: A | text: Io d.sttboinlyIe o n sltr h shlhll ------------------------- ------------------------- key: r | text: m ehkFtl iae ffwmovngnio, eeearegrbn r ------------------------- key: e | text: ufaeiehetnlrIaeii edhdtn t yeteaoeegIe ------------------------- ------------------------- key: d | text: ta mlr dasotwerl a tmwh rn i.t ewn wa ------------------------- key: e | text: riie let bii . ismhehapwnntt hh ioOii ------------------------- key: s | text: n.snriia tlolm ptser.esai eosWeatltnln -------------------------
Скрипт 3
Принимает на вход ключ (если символ ключа - '*', то не преобразует соответствующий символ шифр-текста).
symbl = "qwertyuiopasdfghjklzxcvbnm,./;[]!? QWERTYUIOPASDFGHJKLZXCVBNM"
key_len = 8
key = b'**re*des'
res = ''
for i in range(len(c)):
if key[i % key_len] != b'*'[0]:
key_symbol = key[i % key_len]
else:
key_symbol = 0
res += chr(c[i] ^ key_symbol)
print(res)
Вывод для аргумента '**re*des'
Tmu�t n. f ar.a2easaheImin%YkileroTFr i2Tth li5leDdea5 tat #ins t.alIobl(etio/Z IIwil-Tfa e m8Tfr.Twil p$mi itao assaeeandIthr.ghIme.a5ndIwhe/TitIhasaon pa2, wi- trn 5e nne3Tey toaeeIitsaat. W IIwil-Treainooe t)reIwil-TbeInot)ngG On-
Первый символ ключа выбирается из A
и @
по более осмысленному тексту при соответствующей подстановке.
Вывод для аргумента 'A*re*des'
ITmu�t no f ar. 2eas heImindYkiler.TFr isTth litleDdeat tat bins toalIoblietionZ IIwillTfa e myTfr. ITwil pemi it o ass ee ndIthroghIme. 5ndIwhenTitIhas on pas, wil trn te nnerTey to eeIits at. IIwillTreain.Tgoe threIwillTbeInothngG Onl
Второй символ ключа угадываем из идеи, что строка whenTit
должно отобразиться в when it
, тогда он определяется как chr(ord('T')^ord(' '))
и равен t
.
Пятый символ ключа угадываем из идеи, что строка itIhas
должно отобразиться в itIhas
, тогда он определяется как chr(ord('I')^ord(' '))
и равен i
.
В итоге ключ равен Atreides
а текст расшифровывается в
I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. And when it has gone past, I will turn the inner eye to see its path. Where the fear has gone there will be nothing. Only I will remain.