DIY Rotorchiffer/Subsitutionschiffer i Python

Berätta om dina pågående projekt.
Shimano
Inlägg: 40
Blev medlem: 22 april 2019, 13:13:05

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av Shimano »

Jag kan tydligen dela med mig av en länk så blir det enklare för dom som vill hjälpa mig med koden :)

https://repl.it/@Hackatron/Forkit

Nu har jag skapat stränge message som är "TEST" för att kunna mata krypteringsalgoritmen med textsträngar. Jag omvandlar text strängen till en Integer array, som då blir 19,4,18,9. Detta är bokstävernas ascivärde minus 65.

Det går utmärkt att kryptera en integer array med nummren 19,4,18,19 när den är deklarerad på rad 19, men när jag skrivit över med exakt samma värden från text strängen, så funkar det inte. Någon som förstår varför? Dessutom fastnar koden halvägs in i maskinen av någon anledning, och inte med det samma...

File "main.py", line 61, in <module>
outbyte = i[PosY6]
TypeError: 'int' object is not subscriptable
 ^C
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av johano »

På rad 22 definierar du om "i" till en integer
Shimano
Inlägg: 40
Blev medlem: 22 april 2019, 13:13:05

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av Shimano »

Oj, det borde jag ha sett själv :oops: Tackar!
Shimano
Inlägg: 40
Blev medlem: 22 april 2019, 13:13:05

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av Shimano »

Nu är version 1.0 klar! Jag gjorde följande ändringar:

* Minskade hjulen till 26 steg, enbart engelskt alfabet för enklare hantering
* Text för kryptering kan vara både stora och små bokstäver, men enbart engelska bokstäver
* Blanksteg hanteras som Z i koden, skriver man något med Z får man ett blanksteg istället
* Meddelanden med en längd på max 300 tecken kan kodas

Det finns nu(efter minskningen av stegen) något färre nycklar, totalt är nyckelstorleken ca 72-bitar, fortfarande säkert.

Med mitt chiffer har jag krypterat följande meddelande: TXRTBPTYSLTNIAXBRGVOVMOAUQEHSUWIJUQVETQU

Jag använde meddelande-nyckel 21,5,21,3,6,3,22,13,8,21 och pinn-nyckel 1,15,10,4,6,3,2,1,9,1

Där finns några "ful lösningar" i koden jag ska ge mig in på att försöka fixa, bland annat hur jag ska kunna sätta arrayernas längd efter hur mycket utrymme texten tar. Sedan är också frågan, vad ska chiffret heta? :)

Kod: Markera allt

import array as arr
#Detta är dom fyra kodhjulen
a = arr.array('l', [12,24,16,3,11,4,7,21,19,22,6,1,20,14,15,9,10,25,5,13,23,2,8,17,18,0])
b = arr.array('l', [4,9,18,10,8,13,24,7,5,2,22,14,3,1,25,11,20,0,19,6,15,16,21,23,12,17])
c = arr.array('l', [10,14,4,11,25,17,5,21,23,0,13,18,24,7,1,15,22,20,16,2,6,8,9,3,19,12])
d = arr.array('l', [6,21,19,1,22,18,10,7,3,14,11,15,16,0,8,20,24,25,5,9,23,2,17,13,4,12])
e = arr.array('l', [10,6,24,13,9,25,3,16,23,8,19,15,22,12,21,17,5,1,18,7,2,11,0,20,14,4])
f = arr.array('l', [1,11,17,7,13,16,21,2,24,23,12,4,20,19,15,6,25,14,10,0,18,8,5,22,9,3])
g = arr.array('l', [12,24,16,3,11,4,7,21,19,22,6,1,20,14,15,9,10,25,5,13,23,2,8,17,18,0])
h = arr.array('l', [4,9,18,10,8,13,24,7,5,2,22,14,3,1,25,11,20,0,19,6,15,16,21,23,12,17])
i = arr.array('l', [6,21,19,1,22,18,10,7,3,14,11,15,16,0,8,20,24,25,5,9,23,2,17,13,4,12])
j = arr.array('l', [1,11,17,7,13,16,21,2,24,23,12,4,20,19,15,6,25,14,10,0,18,8,5,22,9,3])

#Meddelandenyckel
msgkey = arr.array('l', [21,5,21,3,6,3,22,13,8,21])
#Meddelandenyckel
pinkey = arr.array('l', [1,15,10,4,6,3,2,1,9,1])
#Meddelandet som ska kodas
msg = arr.array('l', [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1])

#mata in text kortare än 256 tecken
message = input("Enter message(<256): ")
if len(message) > 256:
  print('Message too long')
  exit()

for xy in range(len(message)):
  if ord(message[xy]) == 32:
    msg[xy] = 25
  elif ord(message[xy]) > 96 and ord(message[xy]) < 123:
    msg[xy] = ord(message[xy])-97
  else:
    msg[xy] = ord(message[xy])-65
#det krypterade meddelandet
enc = arr.array('l',[92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92])
#det dekrypterade meddelandet
dec = arr.array('l',[92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92])
#Kodinställning, startpossition per hjul
PosA = msgkey[0]
PosB = msgkey[1]
PosC = msgkey[2]
PosD = msgkey[3]
PosE = msgkey[4]
PosF = msgkey[5]
PosG = msgkey[6]
PosH = msgkey[7]
PosI = msgkey[8]
PosJ = msgkey[9]

#skriv ut meddelandet
#print('Meddelande: ',msg)
#Kyptering
print('Encrypted text: ', end = '')
for x in range(len(message)):
  PosY = (PosA+msg[x])%26
  outbyte = a[PosY]
  PosX = (PosB+outbyte)%26
  outbyte = b[PosX]
  PosZ = (PosC+outbyte)%26
  outbyte = c[PosZ]
  PosY1 = (PosD+outbyte)%26
  outbyte = d[PosY1]
  PosY2 = (PosE+outbyte)%26
  outbyte = e[PosY2]
  PosY3 = (PosF+outbyte)%26
  outbyte = f[PosY3]
  PosY4 = (PosG+outbyte)%26
  outbyte = g[PosY4]
  PosY5 = (PosH+outbyte)%26
  outbyte = h[PosY5]
  PosY6 = (PosI+outbyte)%26
  outbyte = i[PosY6]
  PosY7 = (PosJ+outbyte)%26
  outbyte = j[PosY7]
  enc[x] = outbyte
  print(chr(outbyte+65), end = '')
  
  #Rotering av hjul, efter pinkey.
  PosA = PosA + pinkey[0]
  PosB = PosB + pinkey[1]
  PosC = PosC + pinkey[2]
  PosD = PosD + pinkey[3]
  PosE = PosE + pinkey[4]
  PosF = PosF + pinkey[5]
  PosG = PosG + pinkey[6]
  PosH = PosH + pinkey[7]
  PosI = PosI + pinkey[8]
  PosJ = PosJ + pinkey[9]
  
#print('Krypterat: ',enc)

#Dekryptering, börja med att nollställa nyckeln
PosA = msgkey[0]
PosB = msgkey[1]
PosC = msgkey[2]
PosD = msgkey[3]
PosE = msgkey[4]
PosF = msgkey[5]
PosG = msgkey[6]
PosH = msgkey[7]
PosI = msgkey[8]
PosJ = msgkey[9]

print()
kodat = input("Enter coded text: ")
for xent in range(len(kodat)):
  enc[xent] = ord(kodat[xent])-65

#for x22 in range(len(kodat)):
yent = 0
#Dekryptera, baklänges genom hjulen

for y in range(len(kodat)):
  for x in range(26):
    if j[x] == enc[y]:
        valJ = (x-PosJ)%26
  for x in range(26):
    if i[x] == valJ:
        valI = (x-PosI)%26
  for x in range(26):
    if h[x] == valI:
      valH = (x-PosH)%26
  for x in range(26):
    if g[x] == valH:
      valG = (x-PosG)%26
  for x in range(26):
    if f[x] == valG:
      valF = (x-PosF)%26
  for x in range(26):
    if e[x] == valF:
      valE = (x-PosE)%26
  for x in range(26):
    if d[x] == valE:
      valD = (x-PosD)%26
  for x in range(26):
    if c[x] == valD:
      valC = (x-PosC)%26
  for x in range(26):
    if b[x] == valC:
      valB = (x-PosB)%26
  for x in range(26):
    if a[x] == valB:
      valA = (x-PosA)%26
      dec[y] = valA
    #Rotera hjulen efter pinkey    
  PosA = PosA + pinkey[0]
  PosB = PosB + pinkey[1]
  PosC = PosC + pinkey[2]
  PosD = PosD + pinkey[3]
  PosE = PosE + pinkey[4]
  PosF = PosF + pinkey[5]
  PosG = PosG + pinkey[6]
  PosH = PosH + pinkey[7]
  PosI = PosI + pinkey[8]
  PosJ = PosJ + pinkey[9]
#Skriv ut den dekrypterade texten
#print("Dekrypterat: ",dec)
print('Decrypted text: ', end ='' )
for bx in range(len(dec)):
  if dec[bx] == 25:
    print(' ', end = '')
  else:
    print(chr(dec[bx]+65), end = '')
Shimano
Inlägg: 40
Blev medlem: 22 april 2019, 13:13:05

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av Shimano »

Nu har jag snyggat upp koden en del, och lagt in några mindre ändringar:

* Maxlängd på meddelande är nu 2000 tecken
* Snyggare hantering arrayerna för lagring av meddelandet
* Noggrannare kontroll av inmatning av meddelande för kryptering
* Både stora och små bokstäver fungerar nu unisont

Kod: Markera allt

import array as arr
#Detta är dom fyra kodhjulen
a = arr.array('l', [12,24,16,3,11,4,7,21,19,22,6,1,20,14,15,9,10,25,5,13,23,2,8,17,18,0])
b = arr.array('l', [4,9,18,10,8,13,24,7,5,2,22,14,3,1,25,11,20,0,19,6,15,16,21,23,12,17])
c = arr.array('l', [10,14,4,11,25,17,5,21,23,0,13,18,24,7,1,15,22,20,16,2,6,8,9,3,19,12])
d = arr.array('l', [6,21,19,1,22,18,10,7,3,14,11,15,16,0,8,20,24,25,5,9,23,2,17,13,4,12])
e = arr.array('l', [10,6,24,13,9,25,3,16,23,8,19,15,22,12,21,17,5,1,18,7,2,11,0,20,14,4])
f = arr.array('l', [1,11,17,7,13,16,21,2,24,23,12,4,20,19,15,6,25,14,10,0,18,8,5,22,9,3])
g = arr.array('l', [12,24,16,3,11,4,7,21,19,22,6,1,20,14,15,9,10,25,5,13,23,2,8,17,18,0])
h = arr.array('l', [4,9,18,10,8,13,24,7,5,2,22,14,3,1,25,11,20,0,19,6,15,16,21,23,12,17])
i = arr.array('l', [6,21,19,1,22,18,10,7,3,14,11,15,16,0,8,20,24,25,5,9,23,2,17,13,4,12])
j = arr.array('l', [1,11,17,7,13,16,21,2,24,23,12,4,20,19,15,6,25,14,10,0,18,8,5,22,9,3])

#Maxlängd på text
maxlen = 2000
#Meddelandenyckel
msgkey = arr.array('l', [21,5,21,13,6,3,22,13,8,21])
#Meddelandenyckel
pinkey = arr.array('l', [1,15,10,10,6,3,2,1,9,1])

#Skapa listor för meddelandena
msg = [1,1]
for x in range(maxlen):
  msg.append(1)
#det krypterade meddelandet
enc = [92,92]
for x in range(maxlen):
  enc.append(92)
dec = [92,92]
for x in range(maxlen):
  dec.append(92)

print('Bearfish Cipher 1.1 2019, 72-bit substitution cipher')

#Läs in meddelandet
message = input("Enter message: ")
if len(message) > maxlen:
  print('Message too long')
  exit()
#Kontrollera så att meddelandet inte innehåller förbjudna tecken
for xy in range(len(message)):
  if ord(message[xy]) > 32 and ord(message[xy]) < 65:
    print('Forbidden characters!')
    exit()
  if ord(message[xy]) > 90 and ord(message[xy]) < 97:
    print('Forbidden characters!')
    exit()
  if ord(message[xy]) > 122:
    print('Forbidden characters!')
    exit()
for xy in range(len(message)):
  if ord(message[xy]) == 32:
    msg[xy] = 25
  elif ord(message[xy]) > 96 and ord(message[xy]) < 123:
    msg[xy] = ord(message[xy])-97
  else:
    msg[xy] = ord(message[xy])-65
 #Kodinställning, startpossition per hjul
PosA = msgkey[0]
PosB = msgkey[1]
PosC = msgkey[2]
PosD = msgkey[3]
PosE = msgkey[4]
PosF = msgkey[5]
PosG = msgkey[6]
PosH = msgkey[7]
PosI = msgkey[8]
PosJ = msgkey[9]
 #Kyptering
print('Encrypted text: ', end = '')
for x in range(len(message)):
  PosY = (PosA+msg[x])%26
  outbyte = a[PosY]
  PosX = (PosB+outbyte)%26
  outbyte = b[PosX]
  PosZ = (PosC+outbyte)%26
  outbyte = c[PosZ]
  PosY1 = (PosD+outbyte)%26
  outbyte = d[PosY1]
  PosY2 = (PosE+outbyte)%26
  outbyte = e[PosY2]
  PosY3 = (PosF+outbyte)%26
  outbyte = f[PosY3]
  PosY4 = (PosG+outbyte)%26
  outbyte = g[PosY4]
  PosY5 = (PosH+outbyte)%26
  outbyte = h[PosY5]
  PosY6 = (PosI+outbyte)%26
  outbyte = i[PosY6]
  PosY7 = (PosJ+outbyte)%26
  outbyte = j[PosY7]
  enc[x] = outbyte
  print(chr(outbyte+65), end = '')
    
  #Rotering av hjul, efter pinkey.
  PosA = PosA + pinkey[0]
  PosB = PosB + pinkey[1]
  PosC = PosC + pinkey[2]
  PosD = PosD + pinkey[3]
  PosE = PosE + pinkey[4]
  PosF = PosF + pinkey[5]
  PosG = PosG + pinkey[6]
  PosH = PosH + pinkey[7]
  PosI = PosI + pinkey[8]
  PosJ = PosJ + pinkey[9]
 
#Dekryptering, börja med att nollställa nyckeln
PosA = msgkey[0]
PosB = msgkey[1]
PosC = msgkey[2]
PosD = msgkey[3]
PosE = msgkey[4]
PosF = msgkey[5]
PosG = msgkey[6]
PosH = msgkey[7]
PosI = msgkey[8]
PosJ = msgkey[9]

print()
#Läs in kodad text från kodat till enc
kodat = input("Enter coded text: ")
for xent in range(len(kodat)):
  if ord(kodat[xent]) > 64 and ord(kodat[xent]) < 91:
    enc[xent] = ord(kodat[xent])-65
  elif ord(kodat[xent]) > 96 and ord(kodat[xent]) < 123:
    enc[xent] = ord(kodat[xent])-97
  else:
    print('character error!')
#for x22 in range(len(kodat)):
yent = 0
#Dekryptera, baklänges genom hjulen

for y in range(len(kodat)):
  for x in range(26):
    if j[x] == enc[y]:
        valJ = (x-PosJ)%26
  for x in range(26):
    if i[x] == valJ:
        valI = (x-PosI)%26
  for x in range(26):
    if h[x] == valI:
      valH = (x-PosH)%26
  for x in range(26):
    if g[x] == valH:
      valG = (x-PosG)%26
  for x in range(26):
    if f[x] == valG:
      valF = (x-PosF)%26
  for x in range(26):
    if e[x] == valF:
      valE = (x-PosE)%26
  for x in range(26):
    if d[x] == valE:
      valD = (x-PosD)%26
  for x in range(26):
    if c[x] == valD:
      valC = (x-PosC)%26
  for x in range(26):
    if b[x] == valC:
      valB = (x-PosB)%26
  for x in range(26):
    if a[x] == valB:
      valA = (x-PosA)%26
      dec[y] = valA
    #Rotera hjulen efter pinkey    
  PosA = PosA + pinkey[0]
  PosB = PosB + pinkey[1]
  PosC = PosC + pinkey[2]
  PosD = PosD + pinkey[3]
  PosE = PosE + pinkey[4]
  PosF = PosF + pinkey[5]
  PosG = PosG + pinkey[6]
  PosH = PosH + pinkey[7]
  PosI = PosI + pinkey[8]
  PosJ = PosJ + pinkey[9]
#Skriv ut den dekrypterade texten
#print("Dekrypterat: ",dec)
print('Decrypted text: ', end ='' )
for bx in range(len(dec)):
  if dec[bx] == 25:
    print(' ', end = '')
  else:
    print(chr(dec[bx]+65), end = '')
guckrum
Inlägg: 1683
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av guckrum »

En grej du kan göra är att ta input på stdin och skriva till stdout. Då klarar du av att hantera oändligt långa meddelanden. Dessutom passar det väl in i UNIX-filosofin så att du kan bygga komplexare strukturer med denna "atom".
Shimano
Inlägg: 40
Blev medlem: 22 april 2019, 13:13:05

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av Shimano »

Dagens sista ändringar, version 1.2 :) Namnet på chiffret blir bearfish, alla andra tuffa kryptonamn verkade vara upptagna...

Följande ändringar inlagda:
* Meny loop med val för kryptering/dekryptering/avsluta/visa nycklarna
* Kryptering och dekryptering inlagda i funktioner, för smidighetens skull

Kod: Markera allt

import array as arr

def dispkey():
  print('MSGKEY: ', end = '')
  for x in range(9):
    print(msgkey[x],' ' ,end = '')
  print('')
  print('PINKEY: ', end = '')
  for x in range(9):
    print(pinkey[x],' ', end = '')
  print('')
  return;

def decrypt():
  #Dekryptering, börja med att nollställa nyckeln
  PosA = msgkey[0]
  PosB = msgkey[1]
  PosC = msgkey[2]
  PosD = msgkey[3]
  PosE = msgkey[4]
  PosF = msgkey[5]
  PosG = msgkey[6]
  PosH = msgkey[7]
  PosI = msgkey[8]
  PosJ = msgkey[9]

  print()
  #Läs in kodad text från kodat till enc, kontrollera tecknen
  kodat = input("Enter coded text: ")
  for xent in range(len(kodat)):
    if ord(kodat[xent]) > 64 and ord(kodat[xent]) < 91:
      enc[xent] = ord(kodat[xent])-65
    elif ord(kodat[xent]) > 96 and ord(kodat[xent]) < 123:
      enc[xent] = ord(kodat[xent])-97
    else:
      print('character error!')
  #for x22 in range(len(kodat)):
  yent = 0
  #Dekryptera, baklänges genom hjulen

  for y in range(len(kodat)):
    for x in range(26):
      if j[x] == enc[y]:
          valJ = (x-PosJ)%26
    for x in range(26):
      if i[x] == valJ:
          valI = (x-PosI)%26
    for x in range(26):
      if h[x] == valI:
        valH = (x-PosH)%26
    for x in range(26):
      if g[x] == valH:
        valG = (x-PosG)%26
    for x in range(26):
      if f[x] == valG:
        valF = (x-PosF)%26
    for x in range(26):
      if e[x] == valF:
        valE = (x-PosE)%26
    for x in range(26):
      if d[x] == valE:
        valD = (x-PosD)%26
    for x in range(26):
      if c[x] == valD:
        valC = (x-PosC)%26
    for x in range(26):
      if b[x] == valC:
        valB = (x-PosB)%26
    for x in range(26):
      if a[x] == valB:
        valA = (x-PosA)%26
        dec[y] = valA
      #Rotera hjulen efter pinkey    
    PosA = PosA + pinkey[0]
    PosB = PosB + pinkey[1]
    PosC = PosC + pinkey[2]
    PosD = PosD + pinkey[3]
    PosE = PosE + pinkey[4]
    PosF = PosF + pinkey[5]
    PosG = PosG + pinkey[6]
    PosH = PosH + pinkey[7]
    PosI = PosI + pinkey[8]
    PosJ = PosJ + pinkey[9]
  #Skriv ut den dekrypterade texten
  #print("Dekrypterat: ",dec)
  print('Decrypted text: ', end ='' )
  for bx in range(len(dec)):
    if dec[bx] == 25:
      print(' ', end = '')
    else:
      print(chr(dec[bx]+65), end = '')
  return;

def encrypt():
  #Läs in meddelandet
  message = input("Enter message: ")
  if len(message) > maxlen:
    print('Message too long')
    exit()
  #Kontrollera så att meddelandet inte innehåller förbjudna tecken
  for xy in range(len(message)):
    if ord(message[xy]) > 32 and ord(message[xy]) < 65:
      print('Forbidden characters!')
      exit()
    if ord(message[xy]) > 90 and ord(message[xy]) < 97:
      print('Forbidden characters!')
      exit()
    if ord(message[xy]) > 122:
      print('Forbidden characters!')
      exit()
  for xy in range(len(message)):
    if ord(message[xy]) == 32:
      msg[xy] = 25
    elif ord(message[xy]) > 96 and ord(message[xy]) < 123:
      msg[xy] = ord(message[xy])-97
    else:
      msg[xy] = ord(message[xy])-65
  #Kodinställning, startpossition per hjul
  PosA = msgkey[0]
  PosB = msgkey[1]
  PosC = msgkey[2]
  PosD = msgkey[3]
  PosE = msgkey[4]
  PosF = msgkey[5]
  PosG = msgkey[6]
  PosH = msgkey[7]
  PosI = msgkey[8]
  PosJ = msgkey[9]
  #Kyptering
  print('Encrypted text: ', end = '')
  for x in range(len(message)):
    PosY = (PosA+msg[x])%26
    outbyte = a[PosY]
    PosX = (PosB+outbyte)%26
    outbyte = b[PosX]
    PosZ = (PosC+outbyte)%26
    outbyte = c[PosZ]
    PosY1 = (PosD+outbyte)%26
    outbyte = d[PosY1]
    PosY2 = (PosE+outbyte)%26
    outbyte = e[PosY2]
    PosY3 = (PosF+outbyte)%26
    outbyte = f[PosY3]
    PosY4 = (PosG+outbyte)%26
    outbyte = g[PosY4]
    PosY5 = (PosH+outbyte)%26
    outbyte = h[PosY5]
    PosY6 = (PosI+outbyte)%26
    outbyte = i[PosY6]
    PosY7 = (PosJ+outbyte)%26
    outbyte = j[PosY7]
    enc[x] = outbyte
    print(chr(outbyte+65), end = '')
    
      
    #Rotering av hjul, efter pinkey.
    PosA = PosA + pinkey[0]
    PosB = PosB + pinkey[1]
    PosC = PosC + pinkey[2]
    PosD = PosD + pinkey[3]
    PosE = PosE + pinkey[4]
    PosF = PosF + pinkey[5]
    PosG = PosG + pinkey[6]
    PosH = PosH + pinkey[7]
    PosI = PosI + pinkey[8]
    PosJ = PosJ + pinkey[9]
  print() 
  return;

#Detta är dom fyra kodhjulen
a = arr.array('l', [12,24,16,3,11,4,7,21,19,22,6,1,20,14,15,9,10,25,5,13,23,2,8,17,18,0])
b = arr.array('l', [4,9,18,10,8,13,24,7,5,2,22,14,3,1,25,11,20,0,19,6,15,16,21,23,12,17])
c = arr.array('l', [10,14,4,11,25,17,5,21,23,0,13,18,24,7,1,15,22,20,16,2,6,8,9,3,19,12])
d = arr.array('l', [6,21,19,1,22,18,10,7,3,14,11,15,16,0,8,20,24,25,5,9,23,2,17,13,4,12])
e = arr.array('l', [10,6,24,13,9,25,3,16,23,8,19,15,22,12,21,17,5,1,18,7,2,11,0,20,14,4])
f = arr.array('l', [1,11,17,7,13,16,21,2,24,23,12,4,20,19,15,6,25,14,10,0,18,8,5,22,9,3])
g = arr.array('l', [12,24,16,3,11,4,7,21,19,22,6,1,20,14,15,9,10,25,5,13,23,2,8,17,18,0])
h = arr.array('l', [4,9,18,10,8,13,24,7,5,2,22,14,3,1,25,11,20,0,19,6,15,16,21,23,12,17])
i = arr.array('l', [6,21,19,1,22,18,10,7,3,14,11,15,16,0,8,20,24,25,5,9,23,2,17,13,4,12])
j = arr.array('l', [1,11,17,7,13,16,21,2,24,23,12,4,20,19,15,6,25,14,10,0,18,8,5,22,9,3])

#Maxlängd på text
maxlen = 2000
#Meddelandenyckel
msgkey = arr.array('l', [21,5,21,13,6,3,22,13,8,21])
#Meddelandenyckel
pinkey = arr.array('l', [1,15,10,10,6,3,2,1,9,1])

#Skapa listor för meddelandena
msg = [1,1]
for x in range(maxlen):
  msg.append(1)
#det krypterade meddelandet
enc = [92,92]
for x in range(maxlen):
  enc.append(92)
dec = [92,92]
for x in range(maxlen):
  dec.append(92)

print('Bearfish Cipher 1.1 2019, 72-bit substitution cipher')
while 1:
  print('1: ENCRYPT')
  print('2: DECRYPT')
  print('3: DISPLAY KEYS')
  print('E: EXIT')
  option = input("")
  if option == '1':
    encrypt()
  elif option == '2':
    decrypt()
  elif option == '3':
    dispkey()
  elif option == 'E':
    break
  #Läs in meddelandet

 
guckrum
Inlägg: 1683
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av guckrum »

Ett annat alternativ är att ändra hur hjulen roterar, dvs hur många steg dessa tar efter varje kodning. Om man kan välja att varje hjul ska ta mellan 1 och 10 steg efter varje kodat tecken, så borde det finnas 10 miljarder olika möjligheter, vilket tillsammans med hjulens startpositioner skulle ge 2,4*10^24 möjliga nycklar, 80-bitar.
Nu har jag iofs inte läst din kod, men är det inte så att om du ändrar inkrementet så ändras ordningen på talen som hjulen returnerar?

Om du till exempel har 3 i stället för 29 värden på hjulen, och ett hjul har värdena {1,2,3} samt inkrementet 1 så snurrar den såhär: 1, 2, 3, 1, 2, 3...
Men om inkrementet är 2 läser du ut 1, 3, 2, 1, 3, 2... Och så vidare. Så hjulet {1,2,3} med inkrement 2 är samma sak som hjulet {1,3,2} med inkrement 1.

Så att ändra inkrementet är samma sak som att byta till ett annat hjul. Det ökar inte antalet kombinationer. Eller?
Shimano
Inlägg: 40
Blev medlem: 22 april 2019, 13:13:05

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av Shimano »

Det är en svaghet i kodningen, om "pin key" är jämnt delbart med 26 så blir en del av hjulen oanvända vilket ökar sårbarheten för att bli knäckt. Förmodligen är det bättre att sätta en fast "pin key" med tal som 3,5,6,7,8,12,14,15,16 osv... Då blir nyckelstorleken mindre iofs, kanske får man använda en "plug board" istället, som Enigma och Failka gjorde. Nyckelstorleken är nu 48-bitar, något i nedankant förvisso.

Nu har jag gjort så att den kodade texten presenteras som bokstavskombinationer i steg om fem, XWSTK UIGTH ELPKK FGZHB KWXXA CVOPF UQIYD UEGVE BDMKY DREY. Det blir då enklare att hantera koden manuellt. Det funkar även att läsa in den för att avkodas, mellanslagen sorteras bort. Man kan nu även skapa slumpmässiga nycklar och använda.

Kod: Markera allt

import array as arr
import random

def creatkey():
  print('New key: ', end = '')
  for xint in range(9):
    msgkey[xint] = random.randint(0,25)
    print(msgkey[xint], ' ', end = '')
  print()
  return;

def dispkey():
  print('MSGKEY: ', end = '')
  for x in range(9):
    print(msgkey[x],' ' ,end = '')
  print('')
  return;

def decrypt():
  #Dekryptering, börja med att nollställa nyckeln
  PosA = msgkey[0]
  PosB = msgkey[1]
  PosC = msgkey[2]
  PosD = msgkey[3]
  PosE = msgkey[4]
  PosF = msgkey[5]
  PosG = msgkey[6]
  PosH = msgkey[7]
  PosI = msgkey[8]
  PosJ = msgkey[9]

  print()
  #Läs in kodad text från kodat till enc, kontrollera tecknen
  kodat = input("Enter coded text: ")
  spaces = 0
  
  for xent in range(len(kodat)):
    if ord(kodat[xent]) == 32:
      spaces = spaces + 1
    elif ord(kodat[xent]) > 64 and ord(kodat[xent]) < 91:
      enc[xent-spaces] = ord(kodat[xent])-65
    elif ord(kodat[xent]) > 96 and ord(kodat[xent]) < 123:
      enc[xent-spaces] = ord(kodat[xent])-97
    else:
      print('character error!')
      #exit()
  #for x22 in range(len(kodat)):
  
  yent = 0
  #Dekryptera, baklänges genom hjulen

  for y in range(len(kodat)-spaces):
    for x in range(26):
      if j[x] == enc[y]:
          valJ = (x-PosJ)%26
    for x in range(26):
      if i[x] == valJ:
          valI = (x-PosI)%26
    for x in range(26):
      if h[x] == valI:
        valH = (x-PosH)%26
    for x in range(26):
      if g[x] == valH:
        valG = (x-PosG)%26
    for x in range(26):
      if f[x] == valG:
        valF = (x-PosF)%26
    for x in range(26):
      if e[x] == valF:
        valE = (x-PosE)%26
    for x in range(26):
      if d[x] == valE:
        valD = (x-PosD)%26
    for x in range(26):
      if c[x] == valD:
        valC = (x-PosC)%26
    for x in range(26):
      if b[x] == valC:
        valB = (x-PosB)%26
    for x in range(26):
      if a[x] == valB:
        valA = (x-PosA)%26
        dec[y] = valA
      #Rotera hjulen efter pinkey    
    PosA = PosA + pinkey[0]
    PosB = PosB + pinkey[1]
    PosC = PosC + pinkey[2]
    PosD = PosD + pinkey[3]
    PosE = PosE + pinkey[4]
    PosF = PosF + pinkey[5]
    PosG = PosG + pinkey[6]
    PosH = PosH + pinkey[7]
    PosI = PosI + pinkey[8]
    PosJ = PosJ + pinkey[9]
  #Skriv ut den dekrypterade texten
  #print("Dekrypterat: ",dec)
  print('Decrypted text: ', end ='' )
  for bx in range(len(dec)):
    if dec[bx] == 25:
      print(' ', end = '')
    elif dec[bx] == 92:
      return;
    else:
      print(chr(dec[bx]+65), end = '')
  return;

def encrypt():
  #Läs in meddelandet
  message = input("Enter message: ")
  if len(message) > maxlen:
    print('Message too long')
    exit()
  #Kontrollera så att meddelandet inte innehåller förbjudna tecken
  for xy in range(len(message)):
    if ord(message[xy]) > 32 and ord(message[xy]) < 65:
      print('Forbidden characters!')
      exit()
    if ord(message[xy]) > 90 and ord(message[xy]) < 97:
      print('Forbidden characters!')
      exit()
    if ord(message[xy]) > 122:
      print('Forbidden characters!')
      exit()
  for xy in range(len(message)):
    if ord(message[xy]) == 32:
      msg[xy] = 25
    elif ord(message[xy]) > 96 and ord(message[xy]) < 123:
      msg[xy] = ord(message[xy])-97
    else:
      msg[xy] = ord(message[xy])-65
  #Kodinställning, startpossition per hjul
  PosA = msgkey[0]
  PosB = msgkey[1]
  PosC = msgkey[2]
  PosD = msgkey[3]
  PosE = msgkey[4]
  PosF = msgkey[5]
  PosG = msgkey[6]
  PosH = msgkey[7]
  PosI = msgkey[8]
  PosJ = msgkey[9]
  #Kyptering
  count = 0
  print('Encrypted text: ', end = '')
  for x in range(len(message)):
    count = count + 1
    PosY = (PosA+msg[x])%26
    outbyte = a[PosY]
    PosX = (PosB+outbyte)%26
    outbyte = b[PosX]
    PosZ = (PosC+outbyte)%26
    outbyte = c[PosZ]
    PosY1 = (PosD+outbyte)%26
    outbyte = d[PosY1]
    PosY2 = (PosE+outbyte)%26
    outbyte = e[PosY2]
    PosY3 = (PosF+outbyte)%26
    outbyte = f[PosY3]
    PosY4 = (PosG+outbyte)%26
    outbyte = g[PosY4]
    PosY5 = (PosH+outbyte)%26
    outbyte = h[PosY5]
    PosY6 = (PosI+outbyte)%26
    outbyte = i[PosY6]
    PosY7 = (PosJ+outbyte)%26
    outbyte = j[PosY7]
    enc[x] = outbyte
    print(chr(outbyte+65), end = '')
    if count > 4:
      print(' ', end = '')
      count = 0
      
    #Rotering av hjul, efter pinkey.
    PosA = PosA + pinkey[0]
    PosB = PosB + pinkey[1]
    PosC = PosC + pinkey[2]
    PosD = PosD + pinkey[3]
    PosE = PosE + pinkey[4]
    PosF = PosF + pinkey[5]
    PosG = PosG + pinkey[6]
    PosH = PosH + pinkey[7]
    PosI = PosI + pinkey[8]
    PosJ = PosJ + pinkey[9]
  print() 
  return;

#Detta är dom fyra kodhjulen
a = arr.array('l', [12,24,16,3,11,4,7,21,19,22,6,1,20,14,15,9,10,25,5,13,23,2,8,17,18,0])
b = arr.array('l', [4,9,18,10,8,13,24,7,5,2,22,14,3,1,25,11,20,0,19,6,15,16,21,23,12,17])
c = arr.array('l', [10,14,4,11,25,17,5,21,23,0,13,18,24,7,1,15,22,20,16,2,6,8,9,3,19,12])
d = arr.array('l', [6,21,19,1,22,18,10,7,3,14,11,15,16,0,8,20,24,25,5,9,23,2,17,13,4,12])
e = arr.array('l', [10,6,24,13,9,25,3,16,23,8,19,15,22,12,21,17,5,1,18,7,2,11,0,20,14,4])
f = arr.array('l', [1,11,17,7,13,16,21,2,24,23,12,4,20,19,15,6,25,14,10,0,18,8,5,22,9,3])
g = arr.array('l', [12,24,16,3,11,4,7,21,19,22,6,1,20,14,15,9,10,25,5,13,23,2,8,17,18,0])
h = arr.array('l', [4,9,18,10,8,13,24,7,5,2,22,14,3,1,25,11,20,0,19,6,15,16,21,23,12,17])
i = arr.array('l', [6,21,19,1,22,18,10,7,3,14,11,15,16,0,8,20,24,25,5,9,23,2,17,13,4,12])
j = arr.array('l', [1,11,17,7,13,16,21,2,24,23,12,4,20,19,15,6,25,14,10,0,18,8,5,22,9,3])

#Maxlängd på text
maxlen = 2000
#Meddelandenyckel, mellan 0 och 25
msgkey = arr.array('l', [21,5,21,13,6,3,22,13,8,21])
#Meddelandenyckel
pinkey = arr.array('l', [1,3,1,5,3,7,3,1,3,5])

#Skapa listor för meddelandena
msg = [1,1]
for x in range(maxlen):
  msg.append(1)
#det krypterade meddelandet
enc = [92,92]
for x in range(maxlen):
  enc.append(92)
dec = [92,92]
for x in range(maxlen):
  dec.append(92)

print('Bearfish Cipher 1.2 2019, 48-bit substitution cipher')

while 1:
  print()
  print('1: ENCRYPT')
  print('2: DECRYPT')
  print('3: DISPLAY KEYS')
  print('4: CREATE RANDOM KEY')
  print('E: EXIT')
  option = input("")
  if option == '1':
    encrypt()
  elif option == '2':
    decrypt()
  elif option == '3':
    dispkey()
  elif option == '4':
    creatkey()
  elif option == 'E':
    break
  #Läs in meddelandet

 

Shimano
Inlägg: 40
Blev medlem: 22 april 2019, 13:13:05

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av Shimano »

Äntligen är version 1.3 klar :)

Nu kan man mata in en egen nyckel direkt från tangentbordet, skapa en slumpmässigt vald nyckel eller välja att använda den som finns kodad i programmet. Kanske ska man ta bort den nyckeln och låta användaren ange den externt, eller spara i en fil kanske. En funktion för att radera nyckeln i minnet är också inlagd.

Kod: Markera allt


import array as arr
import random

def erasekey():
  for x in range(9):
    msgkey[x] = 0
  print("memory clear")
  return;

def enterkey():
  for xint in range(10):
    manualkey = int(input("Enter a key(0-25): "))
    if manualkey >= 0 and manualkey < 26:
      msgkey[xint] = manualkey
    else:
      print("invalid key")
      quit()
  print('MSGKEY: ', end = '')
  for x in range(9):
    print(msgkey[x],' ' ,end = '')
  print('')
  return;print(msgkey)
  return;

def creatkey():
  print('New key: ', end = '')
  for xint in range(9):
    msgkey[xint] = random.randint(0,25)
    print(msgkey[xint], ' ', end = '')
  print()
  return;

def dispkey():
  print('MSGKEY: ', end = '')
  for x in range(9):
    print(msgkey[x],' ' ,end = '')
  print('')
  return;

def decrypt():
  #Dekryptering, börja med att nollställa nyckeln
  PosA = msgkey[0]
  PosB = msgkey[1]
  PosC = msgkey[2]
  PosD = msgkey[3]
  PosE = msgkey[4]
  PosF = msgkey[5]
  PosG = msgkey[6]
  PosH = msgkey[7]
  PosI = msgkey[8]
  PosJ = msgkey[9]

  print()
  #Läs in kodad text från kodat till enc, kontrollera tecknen
  kodat = input("Enter coded text: ")
  spaces = 0
  
  for xent in range(len(kodat)):
    if ord(kodat[xent]) == 32:
      spaces = spaces + 1
    elif ord(kodat[xent]) > 64 and ord(kodat[xent]) < 91:
      enc[xent-spaces] = ord(kodat[xent])-65
    elif ord(kodat[xent]) > 96 and ord(kodat[xent]) < 123:
      enc[xent-spaces] = ord(kodat[xent])-97
    else:
      print('character error!')
      #exit()
  #for x22 in range(len(kodat)):
  
  yent = 0
  #Dekryptera, baklänges genom hjulen

  for y in range(len(kodat)-spaces):
    for x in range(26):
      if j[x] == enc[y]:
          valJ = (x-PosJ)%26
    for x in range(26):
      if i[x] == valJ:
          valI = (x-PosI)%26
    for x in range(26):
      if h[x] == valI:
        valH = (x-PosH)%26
    for x in range(26):
      if g[x] == valH:
        valG = (x-PosG)%26
    for x in range(26):
      if f[x] == valG:
        valF = (x-PosF)%26
    for x in range(26):
      if e[x] == valF:
        valE = (x-PosE)%26
    for x in range(26):
      if d[x] == valE:
        valD = (x-PosD)%26
    for x in range(26):
      if c[x] == valD:
        valC = (x-PosC)%26
    for x in range(26):
      if b[x] == valC:
        valB = (x-PosB)%26
    for x in range(26):
      if a[x] == valB:
        valA = (x-PosA)%26
        dec[y] = valA
      #Rotera hjulen efter pinkey    
    PosA = PosA + pinkey[0]
    PosB = PosB + pinkey[1]
    PosC = PosC + pinkey[2]
    PosD = PosD + pinkey[3]
    PosE = PosE + pinkey[4]
    PosF = PosF + pinkey[5]
    PosG = PosG + pinkey[6]
    PosH = PosH + pinkey[7]
    PosI = PosI + pinkey[8]
    PosJ = PosJ + pinkey[9]
  #Skriv ut den dekrypterade texten
  #print("Dekrypterat: ",dec)
  print('Decrypted text: ', end ='' )
  for bx in range(len(dec)):
    if dec[bx] == 25:
      print(' ', end = '')
    elif dec[bx] == 92:
      return;
    else:
      print(chr(dec[bx]+65), end = '')
  return;

def encrypt():
  #Läs in meddelandet
  message = input("Enter message: ")
  if len(message) > maxlen:
    print('Message too long')
    exit()
  #Kontrollera så att meddelandet inte innehåller förbjudna tecken
  for xy in range(len(message)):
    if ord(message[xy]) > 32 and ord(message[xy]) < 65:
      print('Forbidden characters!')
      exit()
    if ord(message[xy]) > 90 and ord(message[xy]) < 97:
      print('Forbidden characters!')
      exit()
    if ord(message[xy]) > 122:
      print('Forbidden characters!')
      exit()
  for xy in range(len(message)):
    if ord(message[xy]) == 32:
      msg[xy] = 25
    elif ord(message[xy]) > 96 and ord(message[xy]) < 123:
      msg[xy] = ord(message[xy])-97
    else:
      msg[xy] = ord(message[xy])-65
  #Kodinställning, startpossition per hjul
  PosA = msgkey[0]
  PosB = msgkey[1]
  PosC = msgkey[2]
  PosD = msgkey[3]
  PosE = msgkey[4]
  PosF = msgkey[5]
  PosG = msgkey[6]
  PosH = msgkey[7]
  PosI = msgkey[8]
  PosJ = msgkey[9]
  #Kyptering
  count = 0
  print('Encrypted text: ', end = '')
  for x in range(len(message)):
    count = count + 1
    PosY = (PosA+msg[x])%26
    outbyte = a[PosY]
    PosX = (PosB+outbyte)%26
    outbyte = b[PosX]
    PosZ = (PosC+outbyte)%26
    outbyte = c[PosZ]
    PosY1 = (PosD+outbyte)%26
    outbyte = d[PosY1]
    PosY2 = (PosE+outbyte)%26
    outbyte = e[PosY2]
    PosY3 = (PosF+outbyte)%26
    outbyte = f[PosY3]
    PosY4 = (PosG+outbyte)%26
    outbyte = g[PosY4]
    PosY5 = (PosH+outbyte)%26
    outbyte = h[PosY5]
    PosY6 = (PosI+outbyte)%26
    outbyte = i[PosY6]
    PosY7 = (PosJ+outbyte)%26
    outbyte = j[PosY7]
    enc[x] = outbyte
    print(chr(outbyte+65), end = '')
    if count > 4:
      print(' ', end = '')
      count = 0
      
    #Rotering av hjul, efter pinkey.
    PosA = PosA + pinkey[0]
    PosB = PosB + pinkey[1]
    PosC = PosC + pinkey[2]
    PosD = PosD + pinkey[3]
    PosE = PosE + pinkey[4]
    PosF = PosF + pinkey[5]
    PosG = PosG + pinkey[6]
    PosH = PosH + pinkey[7]
    PosI = PosI + pinkey[8]
    PosJ = PosJ + pinkey[9]
  print() 
  return;

#Detta är dom fyra kodhjulen
a = arr.array('l', [12,24,16,3,11,4,7,21,19,22,6,1,20,14,15,9,10,25,5,13,23,2,8,17,18,0])
b = arr.array('l', [4,9,18,10,8,13,24,7,5,2,22,14,3,1,25,11,20,0,19,6,15,16,21,23,12,17])
c = arr.array('l', [10,14,4,11,25,17,5,21,23,0,13,18,24,7,1,15,22,20,16,2,6,8,9,3,19,12])
d = arr.array('l', [6,21,19,1,22,18,10,7,3,14,11,15,16,0,8,20,24,25,5,9,23,2,17,13,4,12])
e = arr.array('l', [10,6,24,13,9,25,3,16,23,8,19,15,22,12,21,17,5,1,18,7,2,11,0,20,14,4])
f = arr.array('l', [1,11,17,7,13,16,21,2,24,23,12,4,20,19,15,6,25,14,10,0,18,8,5,22,9,3])
g = arr.array('l', [12,24,16,3,11,4,7,21,19,22,6,1,20,14,15,9,10,25,5,13,23,2,8,17,18,0])
h = arr.array('l', [4,9,18,10,8,13,24,7,5,2,22,14,3,1,25,11,20,0,19,6,15,16,21,23,12,17])
i = arr.array('l', [6,21,19,1,22,18,10,7,3,14,11,15,16,0,8,20,24,25,5,9,23,2,17,13,4,12])
j = arr.array('l', [1,11,17,7,13,16,21,2,24,23,12,4,20,19,15,6,25,14,10,0,18,8,5,22,9,3])

#Maxlängd på text
maxlen = 2000
#Meddelandenyckel, mellan 0 och 25
msgkey = arr.array('l', [21,5,21,13,6,3,22,13,8,21])
#Meddelandenyckel
pinkey = arr.array('l', [1,3,1,5,3,7,3,1,3,5])

#Skapa listor för meddelandena
msg = [1,1]
for x in range(maxlen):
  msg.append(1)
#det krypterade meddelandet
enc = [92,92]
for x in range(maxlen):
  enc.append(92)
dec = [92,92]
for x in range(maxlen):
  dec.append(92)

print('Bearfish Cipher 1.3 2019, 48-bit substitution cipher')

while 1:
  print()
  print('1: ENCRYPT')
  print('2: DECRYPT')
  print('')
  print('3: DISPLAY KEY IN MEMORY')
  print('4: CREATE RANDOM KEY')
  print('5: ENTER KEY MANUALLY')
  print('6: ERASE KEY IN MEMORY')
  print('E: EXIT')
  option = input("")
  if option == '1':
    encrypt()
  elif option == '2':
    decrypt()
  elif option == '3':
    dispkey()
  elif option == '4':
    creatkey()
  elif option == '5':
    enterkey()
  elif option == '6':
    erasekey()
  elif option == 'E':
    break
  #Läs in meddelandet

 

xxargs
Inlägg: 10183
Blev medlem: 23 september 2006, 14:28:27
Ort: Södertälje

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av xxargs »

Har detta fortfarande Enigmas svaghet att den inte kan återge sin egen inmatade tecken i sin utskrift ? - det räckte för att man skulle kunna börja knäcka denna just med vetskapen att alla tecken kunde förekomma utom just den tecknet för meddelandet på den positionen i meddelandet. Enigma använde en korskopplade 'spegel' för att utnyttja rotorerna dubbelt med tänkt högre säkerhet av det, men med detta fick en avgörande svaghet istället.


Till detta behöver nyckellängden vara dubbelt så lång som styrkan i den utkomna datat pga. födelsedags-paradoxen.

tittar man på block-chiper som AES 128, AES 192 och AES 256 så är matade nyckellängderna för själva chipern dubbel långa räknat i antal bit och görs med nyckelexpansion av det ursprungliga 128, 192, 256 bit långa nycklarna.

Fördelsdags-paradoxen gäller också olika hash-algoritmer (dvs sannolikheten att en annan textsträng med kanske annan längd ger samma hash-summa som ursprungliga strängen) och det var brister i SHA1 som gjorde att det till slut är inte rekommenderat användas för tex. hashning av passord - då den pga. interna 'sprickor' i algoritmen liknande ditt:

" Det är en svaghet i kodningen, om "pin key" är jämnt delbart med 26 så blir en del av hjulen oanvända vilket ökar sårbarheten för att bli knäckt"

som beskriver en av många problemmekanismen för de som skriver krypto och hash-algoritmer ganska bra, nu har reducerats från tänkta 80 bit styrka till idag knappt 63-bit styrka, kort sagt det finns kombinationer som aldrig återfinns i utdata för att en del av 'hjulen' aldrig används, oavsett mängd data som processas och innebar med detta att fördelsdagsparadoxsen minskade med ett antal bitar för SHA1.


Slutligen man skall inte använda samma nyckel till för stor mängd data (dvs tillräckligt mycket av kugghjulen roterats) då vid en viss gräns börja läcka info om dess inställning och man kan ana hur hjulen är kopplade mot varandra och därmed knäcka kryptot. Moderna algoritmer för tex. disk-skrivning byter nycklar ganska ofta (enligt NIST max 16 GB storlek innan ny nyckel för AES 128 vid hårddiskkryptering) - förvisso i grunden huvudnyckeln men så modifierar man denna med hashade versioner av LBA-nummer mm. - substituera från föregående blocket eller nästa i olika toplogier beroende om det skall vara blockvis adresserbart eller om det 'går sönder' om en enda bit blir fel i kedjan eller förskjutning för att (ovetande av mottagaren) data saknas.

utmaningen när det gäller blocklagring på tex hårddiskar är att få till den här variationen på oförutsägbar sätt sedd av angriparen utan att behöva lägga till extrainformation eller beroenden av sektor före och efter (som kan ändras oberoende av varandra när som helst)
guckrum
Inlägg: 1683
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av guckrum »

Shimano: Jag menade att du nog inte har så många kombinationer som du antydde. Att lägga in steglängden i nyckeln ökar inte kryptots komplexitet som jag förstår det du gör.

Och du skall se till att steglängden och storleken på hjulen är relativt prima. Enklaste sättet att ordna det på är att sätta hjulstorleken till ett primtal. Som till exempel 29. Inte 26. Då kommer alltid alla värden på hjulen att dyka upp.

xxargs: Ja så var det med Enigma. Jag är ingen expert, men tror att ett par saker till bidrog. Det första var att det är svårt att distribuera nycklar. Man återanvände nycklar, och ibland kom engelsmännen över kodböckerna (Ian Flemming "jobbade" visst med det.) Det andra var att tyskarna var väldigt ordningsamma och inledde flera typer av meddelanden med en väderrapport. Gissar man den är problemet rejält reducerat.

Edit: stavfel
Senast redigerad av guckrum 14 maj 2019, 20:57:22, redigerad totalt 1 gång.
Shimano
Inlägg: 40
Blev medlem: 22 april 2019, 13:13:05

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av Shimano »

Enigma hade svagheten att ett krypterat tecken aldrig kunde bli sig självt, på grund av reflektorn som användes tror jag. Mitt skiffer kan koda bokstäver till sig själva, men har mindre nyckelkomplexitet eftersom jag inte använder någon reflektor som kan varieras. Förmodligen hade det varit bra att gå ner på 23 eller 29 steg på hjulen för att utnyttja alla till fullo, fördelen med 26 är att den krypterade texten på ett enkelt sätt presenteras snyggt och lättöverfört med bokstäverna i engelska alfabetet.

Enigma snurrade hjul nummer två ett steg, när hjul nummer ett hade gått ett varv. Då krävs det att man skriver ganska långa meddelanden innan man använder hela maskinens komplexitet i och för sig, med 10 rotorer är det nog inte möjligt.
Shimano
Inlägg: 40
Blev medlem: 22 april 2019, 13:13:05

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av Shimano »

Version 1.4 ute nu! Fixade lite buggar och lade om hjulstegningarna så att hela rullens komplexitet används. Jag har även inkluderat dom drygt 3,5 miljoner olika möjligheterna som rullarna kan sättas ihop, då kommer man upp i 72-bitar nyckelstorlek.

En plug board skulle kanske kunna vara en möjlighet, får fundera på det.

https://repl.it/@Hackatron/BearFish-cipher
xxargs
Inlägg: 10183
Blev medlem: 23 september 2006, 14:28:27
Ort: Södertälje

Re: DIY Rotorchiffer/Subsitutionschiffer i Python

Inlägg av xxargs »

guckrum skrev:Shimano:

xxargs: Ja så var det med Enigma. Jag är ingen expert, men tror att ett par saker till bidrog. Det första var att det är svårt att distribuera nycklar. Man återanvände nycklar, och ibland kom engelsmännen över kodböckerna (Ian Flemming "jobbade" visst med det.) Det andra var att tyskarna var väldigt ordningsamma och inledde flera typer av meddelanden med en väderrapport. Gissar man den är problemet rejält reducerat.
---

Med reflektorn fick man problemet att strömmen som gick in i i hjulen måste mynna ut på någon annan av 'ingångarna' som då blev utgångarna för att tända en lampa på annan position för en annan tangent för att det skulle bli e elektrisk loop - Man tänkte inte att ge möjligheten till icke tänd lampa skulle tolkas som att samma bokstav som matades in skulle användas - gissar att det var ett praktiskt bekymmer för att man skulle kunna få folk att använda maskinerna samt att tända den lampan som man tryckte ned tangenten på och inte hittade väg till någon annan 'utgång' var för komplext att implementera och man hade heller inte insikten att denna lilla avvikelse kostade väldigt mycket kryptografiskt motstånd mot attack.


---

Dom misstagen tyskarna gjorde gäller i högsta grad än i dag - att veta en del av översändande text vid en attack är en oerhörd hjälp för att minska komplexiteten, då man på vissa ställen vet vad man letar efter - när det gäller hårddiskkryptering så kan man med stor sannolikhet anta att NTFS används och då vet man hur strukturerna ser ut i början av volymen vilket kan hjälpa vid en attack. - det är ingen skillnad att leta efter strukturen för NTFS som att i tyskarnas väderleksrapporter veta vilken inledande hälsningsfras de använde och visste att de så likadant ut var gång

Så ordningsamhet är inte bara ett tyskt problem utan är inbyggt i mycket. återanvändning är också ett vanligt beskymmer - de som inte har återanvänt passord någon gång på någon site eller krypterad arkivvolym någonsin kan räcka upp en hand - bryr mig inte att räkna då det nog finns ingen som helt ärligt kan säga att de har gjort så...

distrubitionen av nycklar är också ett problem - även om fallucke-metoden (RSA) baserat på multiplikationen av väldigt stora primtal med offentlig och privat nyckel har gett en väg som inte fanns före och man var tvungen att fördela nycklar i mer eller mindre öppen form med bud eller att det delades ut innan.

De klassiska engångs-padsen (dvs. nyckeln av sann slumptalsssekvens är lika lång som meddelandet) är fortfarande oknäckbara och bevisat matematiskt att de är så (Shannon var inblandat i det beviset - finns anledning varför diceware har en ordlista på 7776 ord och inte mer eller mindre och kan spåras till just Shannon analyser i hur många olika ord som användes i normal skrift och tal dagligen för en stor grupp människor i ett språktyp) - under förutsättning att de aldrig någonsin återanvänds - och återanvändning var något som skedde under WW2 och det räckte för att man sände samma meddelande 2 gånger för att rätta misstag för den första sändningen utan att chiffrera om för den med ny nyckel för andra sändningen för att ge tillräckligt mycket information för att kunna knäckas. - och detta knäcktes av folk utan datorer, med hjärna, papper och penna endast till hjälp och som bäst senare delar av föregångare till det som senare skulle bli datorer...
Skriv svar