def decrypt(self, ciphertext): """Decrypt ciphertext with key using AES-128-CBC.""" c = chunks(ciphertext, self.keysize) plaintext = xor(super().decrypt(c[0]), self.iv) for i in range(0, len(c) - 1): plaintext += xor(c[i], super().decrypt(c[i + 1])) return plaintext
def encrypt(self, plaintext): """Encrypt ciphertext with key using AES-128-CBC.""" p = chunks(plaintext, self.keysize) c = super().encrypt(xor(p[0], self.iv)) ciphertext = c for chunk in p[1:]: c1 = super().encrypt(xor(c, chunk)) ciphertext += c1 c = c1 return ciphertext
def __init__(self, ciphertext): """Ciphertext to analyze for most likely single-character xor key.""" self.ciphertext = ciphertext self.scores = {} # letter frequency dictionary etaoin = { b"e": 13, b" ": 12, b"t": 11, b"a": 10, b"o": 9, b"i": 8, b"n": 7, b"s": 6, b"h": 5, b"r": 4, b"d": 3, b"l": 2, b"u": 1 } # iterate through all possible keys for key in range(256): key = bytes([key]) full_key = key * len(self.ciphertext) xor_text = xor(self.ciphertext, full_key) # update frequency score self.scores[key] = 0 for c in xor_text: if bytes([c]).lower() in etaoin: self.scores[key] += etaoin[bytes([c]).lower()] elif bytes([c]).isalnum() is False: self.scores[key] -= 1 # most likely key self.key = max(self.scores, key=self.scores.get) self.score = self.scores[self.key]
def decrypt_single_xor_str(s): ''' decrypt_singe_xor_str(str) -> (int, str) Finds the string with the highest number of alphabets and spaces after being single-byte XOR'ed. ''' freq_dict = {} for j in xrange(256): decrypted_str = "" xor_key = hex(j)[2:].zfill(2) freq_dict[xor_key] = {} freq_dict[xor_key]["count"] = 0 for i in xrange(0, len(s), 2): encrypted_str = s[i:i + 2] decrypted_str += c2.xor(encrypted_str, xor_key) decrypted_str = decrypted_str.decode("hex") freq_dict[xor_key]["str"] = decrypted_str for e in decrypted_str: if e.isalpha() or e == " ": freq_dict[xor_key]["count"] += 1 #Finding the maximum count max_count = -1 max_str = "" for k in freq_dict: if int(freq_dict[k]["count"]) > max_count: max_count = freq_dict[k]["count"] max_str = freq_dict[k]["str"] max_key = k print "Almost done" return (max_count, max_str, max_key)
def decrypt_single_xor_str(s): ''' decrypt_singe_xor_str(str) -> (int, str) Finds the string with the highest number of alphabets and spaces after being single-byte XOR'ed. ''' freq_dict = {} for j in xrange(256): decrypted_str = "" xor_key = hex(j)[2:].zfill(2) freq_dict[xor_key] = {} freq_dict[xor_key]["count"] = 0 for i in xrange(0,len(s),2): encrypted_str = s[i:i+2] decrypted_str += c2.xor(encrypted_str, xor_key) decrypted_str = decrypted_str.decode("hex") freq_dict[xor_key]["str"] = decrypted_str for e in decrypted_str: if e.isalpha() or e == " ": freq_dict[xor_key]["count"] += 1 #Finding the maximum count max_count = -1 max_str = "" for k in freq_dict: if int(freq_dict[k]["count"]) > max_count: max_count = freq_dict[k]["count"] max_str = freq_dict[k]["str"] max_key = k print "Almost done" return (max_count, max_str, max_key)
def edit_distance(buffer1, buffer2): """Calculate edit distance between two buffers.""" """ >>> edit_distance(b"this is a test", b"wokka wokka!!!") >>> 37 """ hamm = xor(buffer1, buffer2) cnt = 0 for byte in hamm: cnt += bin(byte).count("1") return cnt
def decrypt(self, ciphertext): """Decrypt ciphertext with key using AES-128-CTR.""" counter = 0 plaintext = b"" c = chunks(ciphertext, 16) for chunk in c: n = len(chunk) keystream = ECB(self.key).encrypt(self.nonce + pack("Q", counter)) plaintext += xor(keystream[0:n], chunk) counter += 1 return plaintext
def __init__(self, ciphertext, keyrange): """Ciphertext and range of key lengths.""" self.ciphertext = ciphertext self.keyrange = keyrange self.keysize = KeySize(self.ciphertext, self.keyrange).keysize self.chunks = chunks(self.ciphertext, self.keysize) self.transposed = transpose(self.chunks, self.keysize) self.key = b"" for chunk in self.transposed: self.key += KeyScore(chunk).key n = len(self.ciphertext) k = self.keysize self.full_key = n // k * self.key + self.key[:n % k] # decrypted plaintext self.plaintext = xor(self.full_key, self.ciphertext)
def score_keys_list(position): # iterate through all possible keys scores = {} for key in range(256): key = bytes([key]) full_key = key * len(position) xor_text = xor(position, full_key) # update frequency score scores[key] = 0 for c in xor_text: if bytes([c]).lower() in etaoin: scores[key] += etaoin[bytes([c]).lower()] elif bytes([c]).isalnum() is False: scores[key] -= 1 # most likely key return scores
def score_keys(position): """Score keys iterating over all possible keys (0-255).""" # iterate through all possible keys scores = {} for key in range(256): key = bytes([key]) full_key = key * len(position) xor_text = xor(position, full_key) # update frequency score scores[key] = 0 for c in xor_text: if bytes([c]).lower() in etaoin: scores[key] += etaoin[bytes([c]).lower()] elif bytes([c]).isalnum() is False: scores[key] -= 1 # most likely key return max(scores, key=scores.get)
def get_xor(self): return challenge_2.xor(plaintext.encode("hex"), self.exp_key)
def decrypt(self): """Decrypt plaintext using brute force.""" return xor(self.ciphertext, self.key * len(self.ciphertext))
# update frequency score scores[key] = 0 for c in xor_text: if bytes([c]).lower() in etaoin: scores[key] += etaoin[bytes([c]).lower()] elif bytes([c]).isalnum() is False: scores[key] -= 1 # most likely key return scores def print_scores(scores): """Print scores for all keys.""" num = 0 print("{:<12} {:<8}".format("Key", "Score")) sorted_scores = sorted(scores.items(), key=lambda x: x[1], reverse=True) for score in sorted_scores: print("{:<12} {:<8}".format(str(score[0]), score[1])) keystream = b"" for t in transposed: keystream += score_keys(t) plaintexts = [] for c in ciphertexts: n = len(c) plaintexts.append(xor(keystream[0:n], c))
def repeating_key_xor_encrypt(plaintext, key): """Encrypts plaintext with repeating-key XOR.""" n = len(plaintext) k = len(key) return xor(n // k * key + key[:n % k], plaintext)
def score_keys(position): """Score keys iterating over all possible keys (0-255).""" # iterate through all possible keys scores = {} for key in range(256): key = bytes([key]) full_key = key * len(position) xor_text = xor(position, full_key) # update frequency score scores[key] = 0 for c in xor_text: if bytes([c]).lower() in etaoin: scores[key] += etaoin[bytes([c]).lower()] elif bytes([c]).isalnum() is False: scores[key] -= 1 # most likely key return max(scores, key=scores.get) keystream = b"" for t in transposed: keystream += score_keys(t) for c in ciphertexts: n = len(c) print(xor(keystream[0:n], c))