Cryptopals Crypto Challenge
hacking
I recently discovered the cryptopals crypto challenges by nccgroup. I’ll be recording my solutions here.
set1
import sys
from Crypto.Cipher import AES
def tobits(s):
result = []
for c in s:
bits = bin(ord(c))[2:]
bits = '00000000'[len(bits):] + bits
result.extend([int(b) for b in bits])
return result
# ----------------------------------
def hexTo64(hex):
return HEX.decode('hex').encode('base64')
def fixedXOR(buf1, buf2):
x = buf1.decode('hex')
y = buf2.decode('hex')
return "".join(chr(ord(a) ^ ord(b)) for a, b in zip(x, y))
#challenge2string1 = '1c0111001f010100061a024b53535009181c'
#challenge2string2 = '686974207468652062756c6c277320657965'
#print fixedXOR(hex1, hex2).encode('hex')
def singleByteXOR(input, key):
output = ""
for i in input:
output += chr(ord(i) ^ ord(key))
return output
# challenge2 end
frequency = {
' ': 20,
'e': 12.02,
't': 9.10,
'a': 8.12,
'o': 7.68,
'i': 7.31,
'n': 6.95,
's': 6.28,
'r': 6.02,
'h': 5.92,
'd': 4.32,
'l': 3.98,
'u': 2.88,
'c': 2.71,
'm': 2.61,
'f': 2.30,
'y': 2.11,
'w': 2.09,
'g': 2.03,
'p': 1.82,
'b': 1.49,
'v': 1.11,
'k': 0.69,
'x': 0.17,
'q': 0.11,
'j': 0.10,
'z': 0.07
}
class Result:
def **init**(self, score, key, result):
self.score = score
self.key = key
self.result = result
def __eq__(self, other):
return self.result == other.result
def __lt__(self, other):
return self.score < other.score
def printObject(self):
print('Key: ' + self.key + " Score: " + str(self.score) + " Phrase: " + str(self.result) + "\n")
def __iter__(self):
return self
def frequencyInEnglish(char):
return frequency.get(char.lower(), 0)
def smartSingleByteXOR(input):
arr = []
options='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 +-:;'
for key in options:
score = 0
result = singleByteXOR(input, key)
for char in result:
if True: # ((ord(char) in range(97,122)) or (ord(char) in range(64i,90) or (ord(char) == 32))):
score += frequencyInEnglish(char)
arr.append(Result(int(100\*(float(score)/float(len(result)))), key, result)) # Return sorted list
arr.sort()
return arr
challengeThreeString='1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736'.decode('hex')
#for ans in smartSingleByteXOR(challengeThreeString):
# ans.printObject()
#print smartSingleByteXOR(challengeThreeString)[-1].printObject()
# challenge 3 end
def detectSingleCharacterXOR(largeFile):
bestCandidates = []
lines = []
with open(largeFile) as f:
lines = f.readlines()
lines = map(lambda x: x.decode('hex'), map(lambda x: x.split('\n')[0], lines))
# print lines
for l in lines:
bestCandidates.append(smartSingleByteXOR(l)[-1])
bestCandidates.sort()
return bestCandidates
# for ans in detectSingleCharacterXOR('4.txt'):
# ans.printObject()
# challenge 4 end
# challenge 5 start
c5input = '''Burning 'em, if you ain't quick and nimble
I go crazy when I hear a cymbal'''
c5output = '0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f'
def repeatedXOR(inputText, key):
output = ""
modValue = len(key)
for i in range(0,len(inputText)):
output += chr(ord(inputText[i]) ^ ord(key[i % modValue]))
return output
#print repeatedXOR(c5input, 'ICE').encode('hex')
#print repeatedXOR(c5output.decode('hex'), 'ICE')
# challenge 5 done
# challenge 6 start
c6example1 = 'this is a test'
c6example2 = 'wokka wokka!!!'
def editDistance(str1, str2):
total = 0
b1 = tobits(str1)
b2 = tobits(str2)
for a,b in zip(b1, b2):
if a != b:
total += 1
return total
# print editDistance(c6example1, c6example2)
def theThreeMostLikelyKeySizes(input):
distances = []
for KEYSIZE in range(2,40):
first = input[ : KEYSIZE]
second = input[KEYSIZE : KEYSIZE * 2]
third = input[KEYSIZE * 2 : KEYSIZE * 3]
fourth = input[KEYSIZE * 3 : KEYSIZE * 4]
normalized = float(editDistance(first, second) + editDistance(second, third) + editDistance(third,fourth)) / (KEYSIZE \* 3)
distances.append((KEYSIZE, normalized))
return map(lambda x: x[0], sorted(distances, key=lambda tup:tup[1])[:3])
fileSix = ''
with open('6.txt', 'r') as myfile:
fileSix=myfile.read().replace('\n', '').decode('base64')
#print theThreeMostLikelyKeySizes(fileSix)
alphabetTestInput = 'abcdefghijklmnopqrstuvwxyz'
def breakIntoBlocksOfSizeN(theFile, n):
output = []
for i in range(0, len(theFile)+1, n):
#print "from: " + str(i) + " to: " + str(i+n-1) + "\n"
output.append(theFile[i:i+n])
return output
#testBrokenBlocks = breakIntoBlocksOfSizeN(fileSix, 29)
#print testBrokenBlocks
def transposeBlocks(blocks, n): # Create array of empty strings, one for each tranposed string
output = [''] \* n # Start sifting bits from each block into correct string
for b in blocks:
for whichBucket in range(0,len(b)):
#print "len is: " + str(len(b))
output[whichBucket] += b[whichBucket]
return output
#print transposeBlocks(testBrokenBlocks, 29)
def breakRepeatKeyXOR(input, keySizes):
finalArr=[]
for KEYSIZE in keySizes:
finalString = ""
transposed = transposeBlocks(breakIntoBlocksOfSizeN(input, KEYSIZE), KEYSIZE)
for t in transposed:
finalString += smartSingleByteXOR(t)[-1].key
finalArr.append(finalString)
return finalArr
#keys = breakRepeatKeyXOR(fileSix,theThreeMostLikelyKeySizes(fileSix))
#print keys
#print repeatedXOR(fileSix, keys[2])
# END 6
# START 7
with open('7.txt', 'r') as myfile:
fileSeven=myfile.read().replace('\n', '').decode('base64')
sevenKey = b'YELLOW SUBMARINE'
aesKey = AES.new(sevenKey, AES.MODE_ECB)
#print aesKey.decrypt(fileSeven)
# END 7
# START 8
fileEightArray = []
with open('8.txt', 'r') as myfile:
fileEight=myfile.read()
fileEight = fileEight.split('\n')
fileEightArray = map(lambda x: x.decode('hex'), fileEight)
#print fileEightArray
## Detect whether ANY blocks of 16 bytes
def howManyUniqueBlocks(arr):
frequencies = []
for item in arr:
frequency = {}
splitByBytes = [item[i:i+16] for i in range(0, len(item), 16)]
for bytes in splitByBytes:
if bytes in frequency:
frequency[bytes] += 1
print item.encode('hex') # FOR THIS CHALLENGE, the only # sequence of bytes > 1 is the answer!!
else:
frequency[bytes] = 1 # Could do further analysis here, but we print the answer above.
#data = ['\x00\x00\x00\x00\x00\x00', '\x00\x00\x00\x00\x00\x00']
howManyUniqueBlocks(fileEightArray)
# d880619740a8a19b7840a8a31c810a3d08649af70dc06f4fd5d2d69c744cd283e2dd0
# 52f6b641dbf9d11b0348542bb5708649af70dc06f4fd5d2d69c744cd2839475c9dfdbc1d46
# 597949d9c7e82bf5a08649af70dc06f4fd5d2d69c744cd28397a93eab8d6aecd56648915478
# 9a6b0308649af70dc06f4fd5d2d69c744cd283d403180c98c8f6db1f2a3f9c4040deb0ab51b29
# 933f2c123c58386b06fba186a
## set 1 end
to be continued....
```
Found a mistake or typo in this post?
Suggest edit
Have a comment? Let me know
This post helpful? Buy me a coffee!
Have a comment? Let me know
This post helpful? Buy me a coffee!