• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Pomoc z funkcją ataku na szyfr

Object Storage Arubacloud
0 głosów
273 wizyt
pytanie zadane 13 września 2020 w Python przez saseta00 Użytkownik (700 p.)

Cześć,

Mam problem z dokończeniem zadania w postaci programu, a mianowicie funkcji BFattackSubst tak aby generowała wszystkie możliwe klucze dla danego przedziału. Całość opiera się o Szyfr Nieregularnej transpozycji (https://mattomatti.com/pl/a35ad). Mógłby ktoś nakierunkować jak się za to zabrać i co wymaga poprawy? Ewentualnie jeśli ktoś byłby chętny napisać funkcję odpłatnie to również byłbym zainteresowany. Dziękuje za każdą pomoc i pozdrawiam. 

def createKey(key):
    dl = len(key)
    values = []
    for i in range(dl):
        values.append(2*int(key[i])+1)
    # print(values)
    return values

def encrypt(txt, vcode):
    txt_dl = len(txt)
    dl = 0  # ile liter mieści tabelka
    k = 0  # ile kolumn ma tabelka
    while dl < txt_dl:
        dl += vcode[k % len(vcode)]
        k += 1

    # print("txt_dl:", txt_dl)
    # print("dl:", dl)
    # print("k", k)

    table = []  # indeksy pierwszych znaków w każdej kolumnie
    table.append(0)
    for j in range(1, k):
        table.append(table[j - 1] + vcode[(j - 1) % len(vcode)])

    # print("table:", table)

    wynik = []
    maxkol = max(vcode)
    maxkol = int((maxkol - 1) / 2)

    # print("maxkol:", maxkol)

    zapis = 0  # ile znakow zostalo zapisane
    for j in range(maxkol, -maxkol-1, -1):
        # print("J:",j)
        for i in range(k):
            # print("I:",i)
            if((vcode[i % len(vcode)] - 1) / 2 >= abs(j)):
                # print("zapis:",zapis)
                # print("table[i]:",table[i])
                if table[i] >= txt_dl:
                    wynik.append("_")
                else:
                    wynik.append(txt[table[i]])
                zapis += 1
                table[i] += 1
    return "".join(wynik)

def decrypt(txt, vcode):
    txt_dl = len(txt)
    dl = 0  # ile liter mieści tabelka
    k = 0  # ile kolumn ma tabelka
    while (dl < txt_dl):
        dl += vcode[k % len(vcode)]
        k += 1

    # print("txt_dl:", txt_dl)
    # print("dl:", dl)
    # print("k", k)

    maxtab = max(vcode)
    table = []
    table.append(0)
    maxtab = int((maxtab - 1) / 2)

    for j in range(maxtab-1, -maxtab-1, -1):
        # print("J:", j)
        table.append(table[- j + maxtab - 1])
        for i in range(k):
            if((vcode[i % len(vcode)] - 1) / 2 >= abs(j + 1)):
                table[- j + maxtab] += 1
    print("TABLE:",table)
    wynik = []
    zapis = 0

    for i in range(k):
        for j in range(int(-(vcode[i % len(vcode)] - 1) / 2), int((vcode[i % len(vcode)] - 1) / 2 + 1)):
            print("I/J/litera",i,j,txt[table[j + maxtab]])
            wynik.append(txt[table[j + maxtab]])
            zapis += 1
            table[j + maxtab]+=1
    return "".join(wynik)

code = '021'
txt = 'TAJNA INFORMACJA'

vcode = createKey(code)
enctxt = encrypt(txt, vcode)
dectxt = decrypt(enctxt, vcode)

print("vcode:", vcode)
print("ENCRYPTED:", enctxt)
print("DECRYPTED:", dectxt)

#  zamiast listy ciag znakow

"""
klucz '021'
 A  R
 JI MA
TNNOA_
 AF C_
    J
ARJIMATNNOA_AFC_ J

dzielniki 18:
1('0'),2('00'),3('1' lub '000'),
6('0100' lub '11' lub '1000' lub '02' lub '20' itp),
9('102' lub '021' lub '0101' itp )

lub (zręczniej w postaci 'vcode'):
1( [1] ), 2( [1,1] ),  3 ( [3] lub [1,1,1] ),
6( [1,3,1,1] lub [3,3] lub [3,1,1,1] lub [1,5] lub [5,1] itp),
9( [3,1,5] lub [1,5,3] lub [1,3,1,3] itp )
"""

"""
Co jeszcze da się zrobić w miarę szybko:
implementować (w rozsądny sposób) atak BruteForcem
z ograniczeniem rozmiaru (ilością komórek) bloku dla szyfrowania (który zadajemy
ciągami cyfr rodzaju '021' lub [1,5,3]) liczbą 10.

Niżej podano przykładową funkcję, generującą wszystkie możliwe klucze
określonego rozmiaru. Z testowania (patrz niżej) wynika, że zaczynając
od rozmiaru bloku 11 BruteForce jest zbyt wolny.
Więc ograniczymy się krótkimi kluczami (dla dłuższych już jest niezbędnym
używanie bardziej zaawansowanych metod, którę już nie zdążycie realizować).

Funkcję 'FindAddons' podaję z tego powodu, że ona zawiera wyłącznie
obliczeniową logikę. A lepiej, jeśli skupicie się na częściach zadania,
bardziej powiązanych z kryptografią.

Co jeszcze pozostało zrobić:
- używając tą funkcję napisać podstawowy 'BruteForce' (sprawdzenie wszystkich
możliwych kluczy, zaczynając od najmniejszego rozmiaru i do 10);
- możliwe rozmiary muszą być dzielnikami długości kryptotekstu;
- w sposób identyczny do przykłądowych
programów ( w plikach w Teams pod numerami 3,4,5,6) dostosować użycie
modułu 'ngram' (i funkcji 'score' z niego) do automatyzowanego sprawdzenia
'czytelności' tekstów, które otrzymujemy po deszyfrowaniu _kryptotekstu_
za pomocą kolejnego klucza. Ta funkcją zwraca ujemne liczby,
czym większa liczba (albo czym mniejsza za modułem) - tym bardziej
prawdopodobne, że otrzymany tekst będzie czytelny. Pliki danych (rodzaju
'english_bigrams.txt' lub 'english_quadgrams.txt') stworzone dla
literackiego angielskiego języka, w którym litery są przekształcone do dużych,
a spację i wszystkie znaki interpunkcyjne są usunięte.

Tzn. tekst(y),
na którym(/których) trzeba testować program, muszą spełniać powyższe warunki.
Pomiędzy innym, to znaczy jeszcze to, że te znaki '_', którę generuję
funkcją deszyfrowania, trzeba usuwać.
"""

from itertools import combinations_with_replacement
from itertools import permutations
import time
import string
import random
import math
from ngram import Ngram_score
# combinations_with_replacement('ABCD', 2)

# n - sum,  returns list of possible lists of elements [1,3,5...] with sum = n
def FindAddons( n ):
    if n % 2 == 0 :
        AddonsNumbers = [ 2*i for i in range( 1, n // 2 +1 ) ]
    else:
        AddonsNumbers = [ 2*i+1 for i in range( (n+1)//2) ]

    lstN = [ 2*i+1 for i in range( (n+1) // 2 ) ]

    Addons1 = []
    sm = 0
    for i in AddonsNumbers :
        for j in combinations_with_replacement( lstN, i ):
            if sum(j) == n:
                Addons1.append( j )
    #print(Addons1)

    Addons2 = []
    for x in Addons1:
        for y in permutations(x):
            #if y not in Addons2 :
            Addons2.append( y )
    #print(Addons2)

    Addons3 = list( set( Addons2) )

    return( [ list( Addons3[i] ) for i in range(len(Addons3)) ] )

def TimeTest():
    for n in range(12):
        t1 = time.time()
        print('n = ', n, '  len(FindAddons(n)) = ', len(FindAddons(n)) )
        print('... time elapsed: ', time.time()-t1,' seconds')
    return()
"""
n =  0   len(FindAddons(n)) =  0
... time elapsed:  0.05337238311767578  seconds
n =  1   len(FindAddons(n)) =  1
... time elapsed:  0.031244754791259766  seconds
n =  2   len(FindAddons(n)) =  1
... time elapsed:  0.015619993209838867  seconds
n =  3   len(FindAddons(n)) =  2
... time elapsed:  0.015590667724609375  seconds
n =  4   len(FindAddons(n)) =  3
... time elapsed:  0.015619754791259766  seconds
n =  5   len(FindAddons(n)) =  5
... time elapsed:  0.015618324279785156  seconds
n =  6   len(FindAddons(n)) =  8
... time elapsed:  0.015624523162841797  seconds
n =  7   len(FindAddons(n)) =  13
... time elapsed:  0.022132396697998047  seconds
n =  8   len(FindAddons(n)) =  21
... time elapsed:  0.04686403274536133  seconds
n =  9   len(FindAddons(n)) =  34
... time elapsed:  0.2372438907623291  seconds
n =  10   len(FindAddons(n)) =  55
... time elapsed:  1.3357844352722168  seconds
n =  11   len(FindAddons(n)) =  89
... time elapsed:  42.12555551528931  seconds
"""

import string
import random
import time
import math
from ngram import Ngram_score

text = "TAJNA INFORMACJA__"
tj = text.upper().replace(" ", "").replace("_", "").replace("1", "").replace("(", "").replace(")", "").replace(".", "").replace(",","").replace("!", "").replace("?", "").replace("-", "")
alfabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

ns = Ngram_score('english_bigrams.txt')

def BFattackSubst(C):

    lista = []

    t2 = time.time()
    for i in range(26):
        t2 = encrypt(C, i)
        lista += [[ns.score(t2), t2]]

    lista.sort()
    lista.reverse()
    print ('zatracono: ', time.time()-t1, 'sekund')
    return lista[:1]

ct = encrypt(tj, 3)

print(BFattackSubst(ct))

 

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

+1 głos
0 odpowiedzi 3,393 wizyt
pytanie zadane 23 listopada 2019 w Python przez Nieprofesjonalny Użytkownik (890 p.)
+1 głos
2 odpowiedzi 1,583 wizyt
pytanie zadane 1 marca 2017 w C i C++ przez Krystek102 Bywalec (2,440 p.)
0 głosów
2 odpowiedzi 829 wizyt
pytanie zadane 26 lutego 2016 w C i C++ przez rafalmagician Obywatel (1,320 p.)

92,539 zapytań

141,382 odpowiedzi

319,480 komentarzy

61,928 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...