[Kryptographie] Verschlüsselung knacken

21.08.2012 09:59 Uhr
$enc = "2A 02 14 44 05 0A 16 04 0D 03 43";	// hex
$s_len = strlen($s);	// 11
$key_len = strlen($key);	// 3


Aufgabe
$s = ?, $key = ? (Methode XOR)

2 Antworten

#1

22.08.2012 00:14 Uhr
$answerMessage = "25 21 31 21 2c 27 3d 6d 2b 2d 3f 26 20";

;-)

Die Lösung packe ich nicht im Klartext hier rein, da z.B. über Nutzerprofile Antworten eingesehen werden können. Den Bugreport habe ich bereits versandt.

Die Aufgabe war schön. :-)

#2

23.08.2012 15:25 Uhr

$s = 'Now hiring.'

$key = 'dmc'

XOR-Verschlüsselung kann nur über Bruteforce geknackt werden, es können allerdings einige Ergebnisse gefiltert werden, sofern man weiß, in welcher Sprache die ürsprüngliche Nachricht geschrieben wurde.

Das folgende Python-Script entschlüsselt die Nachricht. Es filtert einen Großteil der Ergebnisse heraus, so dass nur "wenige" übrig bleiben.

#!/bin/python

enc = '2A 02 14 44 05 0A 16 04 0D 03 43'	# hex
#s_len = strlen($s);	# 11
#key_len = strlen($key);	# 3
key_len = 3

enc = enc.split()
# Convert enc strings to integers
enc = [int(num, 16) for num in enc]

print enc

# Extract sub sequences
sub_encs = [enc[::key_len], enc[1::key_len], enc[2::key_len]]

min_valid_char = 32 # space
max_valid_char = 126 # ~

valid_enc = [[], [], []]

for key_part in range(256):
  for sub_idx, sub_enc in enumerate(sub_encs):
    is_valid = True
    for num in sub_enc:
      decoded = num ^ key_part
      if decoded < min_valid_char or decoded > max_valid_char:
        # invalid key part for this sub sequence
        is_valid = False
        break
    if is_valid:
      valid_enc[sub_idx].append(key_part)
      
print valid_enc
print len(valid_enc[0])
print len(valid_enc[1])
print len(valid_enc[2])
print 'Possiblities: ' + str(len(valid_enc[0]) * len(valid_enc[1]) * len(valid_enc[2]))

def is_vowel(char):
  return char == 'A' or char == 'E' or char == 'U' or char == 'I' or char == 'O' \
      or char == 'a' or char == 'e' or char == 'u' or char == 'i' or char == 'o'

def is_digit(char):
  return char >= '0' and char <= '9'
  
def is_special_char(char):
  return (char >= '!' and char <= '/') or (char >= ':' and char <= '@') \
      or (char >= '[' and char <= '`') or (char >= '{')

def filter_and_print(key, decrypted):
  if is_special_char(decrypted[0]) or \
     is_digit(decrypted[0]) or is_digit(decrypted[-1]):
    return

  vowels = 0
  spaces = 0
  special = 0
  digits = 0
  for char in decrypted:
    if char == ' ':
      spaces += 1
    elif is_vowel(char):
      vowels += 1
    elif is_digit(char):
      digits += 1
    elif is_special_char(char):
      special += 1
  
  if spaces < 1 or vowels < 2 or special > 1 or digits > 1:
    return
  
  print decrypted + ' [' + chr(key[0]) + chr(key[1]) + chr(key[2]) + ']'


key = [0, 0, 0]
for key_part1 in valid_enc[0]:
  key[0] = key_part1
  for key_part2 in valid_enc[1]:
    key[1] = key_part2
    for key_part3 in valid_enc[2]:
      key[2] = key_part3
      # Decrypt message
      msg = ''
      sub_seq = 0
      for num in enc:
        char = num ^ key[sub_seq]
        sub_seq += 1
        if sub_seq == 3:
          sub_seq = 0
        msg += str(chr(char))
      filter_and_print(key, msg)

Ähnliche Fragen



Datenschutzerklärung · Impressum