Криптография/Блочные шифры. Атаки на блочные шифры: различия между версиями
| Dzeni (обсуждение | вклад) | Dzeni (обсуждение | вклад) | ||
| (не показана 1 промежуточная версия этого же участника) | |||
| Строка 22: | Строка 22: | ||
| ====Скрипт:==== | ====Скрипт:==== | ||
| <syntaxhighlight lang="python"> | <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 > | </syntaxhighlight > | ||
| Вывод: | Вывод: | ||
| <pre> | <pre> | ||
| key  | key  114 str  Unn!fnne!un!cd!ustd | ||
| key  | key  115 str  Too good to be true | ||
| </pre> | </pre> | ||
| === Задание 2=== | === Задание 2=== | ||
| Строка 47: | Строка 52: | ||
| Определяет длину ключа. | Определяет длину ключа. | ||
| <syntaxhighlight lang="python"> | <syntaxhighlight lang="python"> | ||
| symbl = "qwertyuiopasdfghjklzxcvbnm,./;'[]!? QWERTYUIOPASDFGHJKLZXCVBNM" | |||
| def count_weight(num): | |||
| 	return bin(num).count('1') | |||
| def foo(str, key_len): | |||
| 	weight = 0 | |||
| def  | 	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)		 | |||
| print(' | 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> | </syntaxhighlight> | ||
| Строка 76: | Строка 76: | ||
| <pre> | <pre> | ||
| Calculating Hamming distance | Calculating Hamming distance | ||
| 8   2. | 8   2.498360655737705 | ||
| 16   2. | 16   2.5311475409836066 | ||
| 24   2. | 24   2.6950819672131145 | ||
| 32   2.675409836065574 | |||
| </pre> | </pre> | ||
| Строка 88: | Строка 87: | ||
| Принимает на вход длину блока (разбивает строку на сеты и ломает каждый как однобайтовый xor-шифр):   | Принимает на вход длину блока (разбивает строку на сеты и ломает каждый как однобайтовый xor-шифр):   | ||
| <syntaxhighlight lang="python"> | <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') | print('Finding possible keys\n') | ||
| for  | |||
| 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) |      print('-'*25) | ||
| </syntaxhighlight> | </syntaxhighlight> | ||
| Строка 127: | Строка 123: | ||
| Finding possible keys | 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> | </pre> | ||
| Строка 149: | Строка 143: | ||
| Принимает на вход ключ (если символ ключа - '*', то не преобразует соответствующий символ шифр-текста). | Принимает на вход ключ (если символ ключа - '*', то не преобразует соответствующий символ шифр-текста). | ||
| <syntaxhighlight lang="python"> | <syntaxhighlight lang="python"> | ||
| symbl = "qwertyuiopasdfghjklzxcvbnm,./;[]!? QWERTYUIOPASDFGHJKLZXCVBNM" | |||
| key_len = 8 | |||
| key = b'**re*des' | |||
| key =  | |||
| res = '' | |||
| for i in range(len( | for i in range(len(c)): | ||
|      if key[i%key_len] = |      if key[i % key_len] != b'*'[0]: | ||
|          key_symbol = key[i % key_len] | |||
|      else: |      else: | ||
|          key_symbol = 0 | |||
|     res += chr(c[i] ^ key_symbol) | |||
| print( | print(res) | ||
| </syntaxhighlight > | </syntaxhighlight > | ||
| Вывод для аргумента ' | Вывод для аргумента '**re*des' | ||
| <pre> | <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> | </pre> | ||
| Второй символ ключа угадываем из идеи, что строка <code> | Первый символ ключа выбирается из <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> | <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> | ||
Текущая версия от 10: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.