mirror of
https://github.com/20kaushik02/CSE548_ACNS_Work.git
synced 2025-12-06 06:24:07 +00:00
1.2b julia done
This commit is contained in:
parent
8b7829025e
commit
48f130fe73
@ -1,7 +1,6 @@
|
||||
a - caesar
|
||||
left shift:
|
||||
ROPORTIONATELYQUIDSMEDALLIONMICHELOBSICEBOXWEAKFISHSCUSTOMSINDOCTRINATEINQUIRERSANCTIFIEDCHAFFSEISMOLOGYSPERCALESCHISHOLMSBRAGGERSSTUMBLEDTWERKINGUROLOGISTSPROSPECTUSESBUNSENPRISSIESTINQUIRINGBRANCHES
|
||||
|
||||
(right shift gave:)
|
||||
NKLKNPEKJWPAHUMQEZOIAZWHHEKJIEYDAHKXOEYAXKTSAWGBEODOYQOPKIOEJZKYPNEJWPAEJMQENANOWJYPEBEAZYDWBBOAEOIKHKCUOLANYWHAOYDEODKHIOXNWCCANOOPQIXHAZPSANGEJCQNKHKCEOPOLNKOLAYPQOAOXQJOAJLNEOOEAOPEJMQENEJCXNWJYDAO
|
||||
which is not english text, also sha512 sum doesn't match
|
||||
@ -10,8 +9,13 @@ a - julia
|
||||
(the thing has a space at the end lol)
|
||||
mile Vinay and Joseph Gaussinthough not with the speed and ease of a typewriter keyboard. Rather it was the assimilation of encipherment into the overall communication process. Vernam created what came to be called "on-line encipherment" (because it was done directly on the open telegraph circuit) to distinguish it from the old, separate, off-line encipherment. He freed a fundamental process in cryptography from the shackles of time and error. He eliminated a human beingthe cipher clerkfrom the chain of communication. His great contribution was to bring to cryptography the automation that had benefited mankind so much in so many fields of endeavor. These values were immediately recognized, and Ver-nam's idea quickly kicked up a flurry of activity. He put it down on paper in a sketch dated December 17. A.T. & T. notified the Navy, with which it had worked closely in a communications demonstration the previous year, and on February 18, 1918, Vernam, Parker, Lyman F. Morehouse, equipment
|
||||
|
||||
|
||||
b - caesar
|
||||
simply bruteforce, only 26 possibilities
|
||||
key shift 3, left shift gives:
|
||||
EMASWALDSRINGSHIGHLANDSSNOOTIESTASCENDSETTERSFLARESTHINKINGSCARPINGSEDERSSWELLEDMERCILESSOVERSENSITIVEADVENTURERDIVANSYPSILANTISJOCASTAHEADRESTSDISSERTATIONSJOISTSBUSSSERAPUPPETRYSBUNTEDAMPHITHEATRESSTEREOSUNJUSTIFIEDZEPHYRUSSABDICATIONSHUSSERLPALMISTFERALMANNERLEONIDSDILLONSWHEREFORESFERTILIZEDDUCKBILLDUNNESSCORESHAIRCUTBOTTICELLIREPELGLIDESFELICESBRAINSTORMINGSCLEMENCYREDOINGMEDICAIDSBLUNDERBUSS
|
||||
|
||||
b - julia
|
||||
b - julia
|
||||
gzip header includes filename. filename is 14 chars, key is 12 chars, so first and thirteenth character have same key byte, get rotation from that and then
|
||||
(the thing has a space at the end lol, also intentional typos?)
|
||||
All work and no play makes Jack a dull boy.All work and no play makes Jack a dull boy.All woRk and no play makes Jack a dull boy.All work and ho play maoes Jack a dull boy.All work and no plAy makes Jack a dull boy.Alk work and no plAy makes Jack a dull boy.All work and no play makes Jack a dull boy.All work and no pLay maksa Jack a dull boy.All work and no play makes Jack a dull boy.All
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
with open("3/withoutkey/ciphertext.txt", "r") as caesar_cipher_file:
|
||||
caesar_cipher_content = caesar_cipher_file.read()
|
||||
|
||||
for key_shift in range(1,27): # both left and right, 13x2=26
|
||||
for key_shift in range(1,14): # both left and right, 13x2=26
|
||||
print("key shift", key_shift)
|
||||
|
||||
caesar_plaintext_content_left_shift = ""
|
||||
|
||||
44
hw1.2/commontarball/buildkey-givetostudents.py
Normal file
44
hw1.2/commontarball/buildkey-givetostudents.py
Normal file
@ -0,0 +1,44 @@
|
||||
# Read the top of streamy.py for usage, and see line 23 of this file
|
||||
from aes import AESCipher
|
||||
from Crypto.Util.number import bytes_to_long
|
||||
from Crypto.Util.number import long_to_bytes
|
||||
import textwrap
|
||||
import fileinput
|
||||
|
||||
def wrap64(string):
|
||||
return '\n'.join(textwrap.wrap(string,64))
|
||||
|
||||
bitsknownint = 0
|
||||
|
||||
for line in fileinput.input():
|
||||
if len(line) > 10:
|
||||
firstline = line
|
||||
if (len(line) % 2 == 0):
|
||||
firstline = '0' + line
|
||||
continue
|
||||
x, y = map(int, line.split())
|
||||
hint = ((x - 1) << 7) | (y - 32)
|
||||
tryabit = hint & 1
|
||||
i = hint >> 1
|
||||
# All you have to do is figure out what YYY and ZZZ should be...
|
||||
if (YYY):
|
||||
ZZZ
|
||||
|
||||
#while (len(bitsknown) < 256):
|
||||
# i = 255 - len(bitsknown)
|
||||
#for tryabit in ['0', '1']:
|
||||
#hint = (i << 1) + int(tryabit)
|
||||
#bitsknown = str(tryabit) + bitsknown
|
||||
|
||||
AESkey = long_to_bytes(bitsknownint, 32)
|
||||
aes = AESCipher(AESkey)
|
||||
print(firstline)
|
||||
print(len(firstline))
|
||||
eavesdroppedaes = bytes.fromhex(firstline)
|
||||
#('088d72fda25863ae81a27ddc286ee8ffef55bdcd0eeee4487fa42cb9c012155e6c38a32d741c68aaa86fda4c9878cbb4')
|
||||
print('Recovered plaintext is: {}'.format(aes.decrypt(eavesdroppedaes)[:400]))
|
||||
printme = "{0:b}".format(bitsknownint)
|
||||
while len(printme) < 256:
|
||||
printme = '0' + printme
|
||||
print(wrap64(printme))
|
||||
|
||||
BIN
hw1.2/commontarball/part4ciphertext.bin
Normal file
BIN
hw1.2/commontarball/part4ciphertext.bin
Normal file
Binary file not shown.
409
hw1.2/commontarball/rijndael-fewerrounds.py
Normal file
409
hw1.2/commontarball/rijndael-fewerrounds.py
Normal file
@ -0,0 +1,409 @@
|
||||
import string
|
||||
import copy
|
||||
# Modified for CSE 365 by reducing the number of rounds
|
||||
# Create a plaintext.bin and key.bin to test...
|
||||
# dd if=/dev/urandom of=key.bin bs=16 count=1
|
||||
# dd if=/dev/urandom of-plaintext.bin bs=1024 count=1024
|
||||
# python2 rijndael-fewerrounds.py
|
||||
# md5sum *
|
||||
|
||||
#############################################################################
|
||||
# Original code ported from the Java reference code by Bram Cohen, April 2001,
|
||||
# with the following statement:
|
||||
#
|
||||
# this code is public domain, unless someone makes
|
||||
# an intellectual property claim against the reference
|
||||
# code, in which case it can be made public domain by
|
||||
# deleting all the comments and renaming all the variables
|
||||
#
|
||||
class Rijndael(object):
|
||||
"""
|
||||
A pure python (slow) implementation of rijndael with a decent interface.
|
||||
|
||||
To do a key setup::
|
||||
|
||||
r = Rijndael(key, block_size = 16)
|
||||
|
||||
key must be a string of length 16, 24, or 32
|
||||
blocksize must be 16, 24, or 32. Default is 16
|
||||
|
||||
To use::
|
||||
|
||||
ciphertext = r.encrypt(plaintext)
|
||||
plaintext = r.decrypt(ciphertext)
|
||||
|
||||
If any strings are of the wrong length a ValueError is thrown
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def create(cls):
|
||||
|
||||
if hasattr(cls, "RIJNDAEL_CREATED"):
|
||||
return
|
||||
|
||||
# [keysize][block_size]
|
||||
#cls.num_rounds = {16: {16: 10, 24: 12, 32: 14}, 24: {16: 12, 24: 12, 32: 14}, 32: {16: 14, 24: 14, 32: 14}}
|
||||
# Modified for CSE 365 to reduce rounds to 3
|
||||
cls.num_rounds = {16: {16: 3, 24: 3, 32: 3}, 24: {16: 3, 24: 3, 32: 3}, 32: {16: 3, 24: 3, 32: 3}}
|
||||
|
||||
cls.shifts = [[[0, 0], [1, 3], [2, 2], [3, 1]],
|
||||
[[0, 0], [1, 5], [2, 4], [3, 3]],
|
||||
[[0, 0], [1, 7], [3, 5], [4, 4]]]
|
||||
|
||||
A = [[1, 1, 1, 1, 1, 0, 0, 0],
|
||||
[0, 1, 1, 1, 1, 1, 0, 0],
|
||||
[0, 0, 1, 1, 1, 1, 1, 0],
|
||||
[0, 0, 0, 1, 1, 1, 1, 1],
|
||||
[1, 0, 0, 0, 1, 1, 1, 1],
|
||||
[1, 1, 0, 0, 0, 1, 1, 1],
|
||||
[1, 1, 1, 0, 0, 0, 1, 1],
|
||||
[1, 1, 1, 1, 0, 0, 0, 1]]
|
||||
|
||||
# produce log and alog tables, needed for multiplying in the
|
||||
# field GF(2^m) (generator = 3)
|
||||
alog = [1]
|
||||
for i in xrange(255):
|
||||
j = (alog[-1] << 1) ^ alog[-1]
|
||||
if j & 0x100 != 0:
|
||||
j ^= 0x11B
|
||||
alog.append(j)
|
||||
|
||||
log = [0] * 256
|
||||
for i in xrange(1, 255):
|
||||
log[alog[i]] = i
|
||||
|
||||
# multiply two elements of GF(2^m)
|
||||
def mul(a, b):
|
||||
if a == 0 or b == 0:
|
||||
return 0
|
||||
return alog[(log[a & 0xFF] + log[b & 0xFF]) % 255]
|
||||
|
||||
# substitution box based on F^{-1}(x)
|
||||
box = [[0] * 8 for i in xrange(256)]
|
||||
box[1][7] = 1
|
||||
for i in xrange(2, 256):
|
||||
j = alog[255 - log[i]]
|
||||
for t in xrange(8):
|
||||
box[i][t] = (j >> (7 - t)) & 0x01
|
||||
|
||||
B = [0, 1, 1, 0, 0, 0, 1, 1]
|
||||
|
||||
# affine transform: box[i] <- B + A*box[i]
|
||||
cox = [[0] * 8 for i in xrange(256)]
|
||||
for i in xrange(256):
|
||||
for t in xrange(8):
|
||||
cox[i][t] = B[t]
|
||||
for j in xrange(8):
|
||||
cox[i][t] ^= A[t][j] * box[i][j]
|
||||
|
||||
# cls.S-boxes and inverse cls.S-boxes
|
||||
cls.S = [0] * 256
|
||||
cls.Si = [0] * 256
|
||||
for i in xrange(256):
|
||||
cls.S[i] = cox[i][0] << 7
|
||||
for t in xrange(1, 8):
|
||||
cls.S[i] ^= cox[i][t] << (7-t)
|
||||
cls.Si[cls.S[i] & 0xFF] = i
|
||||
|
||||
# T-boxes
|
||||
G = [[2, 1, 1, 3],
|
||||
[3, 2, 1, 1],
|
||||
[1, 3, 2, 1],
|
||||
[1, 1, 3, 2]]
|
||||
|
||||
AA = [[0] * 8 for i in xrange(4)]
|
||||
|
||||
for i in xrange(4):
|
||||
for j in xrange(4):
|
||||
AA[i][j] = G[i][j]
|
||||
AA[i][i+4] = 1
|
||||
|
||||
for i in xrange(4):
|
||||
pivot = AA[i][i]
|
||||
if pivot == 0:
|
||||
t = i + 1
|
||||
while AA[t][i] == 0 and t < 4:
|
||||
t += 1
|
||||
assert t != 4, 'G matrix must be invertible'
|
||||
for j in xrange(8):
|
||||
AA[i][j], AA[t][j] = AA[t][j], AA[i][j]
|
||||
pivot = AA[i][i]
|
||||
for j in xrange(8):
|
||||
if AA[i][j] != 0:
|
||||
AA[i][j] = alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255]
|
||||
for t in xrange(4):
|
||||
if i != t:
|
||||
for j in xrange(i+1, 8):
|
||||
AA[t][j] ^= mul(AA[i][j], AA[t][i])
|
||||
AA[t][i] = 0
|
||||
|
||||
iG = [[0] * 4 for i in xrange(4)]
|
||||
|
||||
for i in xrange(4):
|
||||
for j in xrange(4):
|
||||
iG[i][j] = AA[i][j + 4]
|
||||
|
||||
def mul4(a, bs):
|
||||
if a == 0:
|
||||
return 0
|
||||
r = 0
|
||||
for b in bs:
|
||||
r <<= 8
|
||||
if b != 0:
|
||||
r = r | mul(a, b)
|
||||
return r
|
||||
|
||||
cls.T1 = []
|
||||
cls.T2 = []
|
||||
cls.T3 = []
|
||||
cls.T4 = []
|
||||
cls.T5 = []
|
||||
cls.T6 = []
|
||||
cls.T7 = []
|
||||
cls.T8 = []
|
||||
cls.U1 = []
|
||||
cls.U2 = []
|
||||
cls.U3 = []
|
||||
cls.U4 = []
|
||||
|
||||
for t in xrange(256):
|
||||
s = cls.S[t]
|
||||
cls.T1.append(mul4(s, G[0]))
|
||||
cls.T2.append(mul4(s, G[1]))
|
||||
cls.T3.append(mul4(s, G[2]))
|
||||
cls.T4.append(mul4(s, G[3]))
|
||||
|
||||
s = cls.Si[t]
|
||||
cls.T5.append(mul4(s, iG[0]))
|
||||
cls.T6.append(mul4(s, iG[1]))
|
||||
cls.T7.append(mul4(s, iG[2]))
|
||||
cls.T8.append(mul4(s, iG[3]))
|
||||
|
||||
cls.U1.append(mul4(t, iG[0]))
|
||||
cls.U2.append(mul4(t, iG[1]))
|
||||
cls.U3.append(mul4(t, iG[2]))
|
||||
cls.U4.append(mul4(t, iG[3]))
|
||||
|
||||
# round constants
|
||||
cls.rcon = [1]
|
||||
r = 1
|
||||
for t in xrange(1, 30):
|
||||
r = mul(2, r)
|
||||
cls.rcon.append(r)
|
||||
|
||||
cls.RIJNDAEL_CREATED = True
|
||||
|
||||
def __init__(self, key, block_size = 16):
|
||||
|
||||
# create common meta-instance infrastructure
|
||||
self.create()
|
||||
|
||||
if block_size != 16 and block_size != 24 and block_size != 32:
|
||||
raise ValueError('Invalid block size: ' + str(block_size))
|
||||
if len(key) != 16 and len(key) != 24 and len(key) != 32:
|
||||
raise ValueError('Invalid key size: ' + str(len(key)))
|
||||
self.block_size = block_size
|
||||
|
||||
ROUNDS = Rijndael.num_rounds[len(key)][block_size]
|
||||
BC = block_size / 4
|
||||
# encryption round keys
|
||||
Ke = [[0] * BC for i in xrange(ROUNDS + 1)]
|
||||
# decryption round keys
|
||||
Kd = [[0] * BC for i in xrange(ROUNDS + 1)]
|
||||
ROUND_KEY_COUNT = (ROUNDS + 1) * BC
|
||||
KC = len(key) / 4
|
||||
|
||||
# copy user material bytes into temporary ints
|
||||
tk = []
|
||||
for i in xrange(0, KC):
|
||||
tk.append((ord(key[i * 4]) << 24) | (ord(key[i * 4 + 1]) << 16) |
|
||||
(ord(key[i * 4 + 2]) << 8) | ord(key[i * 4 + 3]))
|
||||
|
||||
# copy values into round key arrays
|
||||
t = 0
|
||||
j = 0
|
||||
while j < KC and t < ROUND_KEY_COUNT:
|
||||
Ke[t / BC][t % BC] = tk[j]
|
||||
Kd[ROUNDS - (t / BC)][t % BC] = tk[j]
|
||||
j += 1
|
||||
t += 1
|
||||
tt = 0
|
||||
rconpointer = 0
|
||||
while t < ROUND_KEY_COUNT:
|
||||
# extrapolate using phi (the round key evolution function)
|
||||
tt = tk[KC - 1]
|
||||
tk[0] ^= (Rijndael.S[(tt >> 16) & 0xFF] & 0xFF) << 24 ^ \
|
||||
(Rijndael.S[(tt >> 8) & 0xFF] & 0xFF) << 16 ^ \
|
||||
(Rijndael.S[ tt & 0xFF] & 0xFF) << 8 ^ \
|
||||
(Rijndael.S[(tt >> 24) & 0xFF] & 0xFF) ^ \
|
||||
(Rijndael.rcon[rconpointer] & 0xFF) << 24
|
||||
rconpointer += 1
|
||||
if KC != 8:
|
||||
for i in xrange(1, KC):
|
||||
tk[i] ^= tk[i-1]
|
||||
else:
|
||||
for i in xrange(1, KC / 2):
|
||||
tk[i] ^= tk[i-1]
|
||||
tt = tk[KC / 2 - 1]
|
||||
tk[KC / 2] ^= (Rijndael.S[ tt & 0xFF] & 0xFF) ^ \
|
||||
(Rijndael.S[(tt >> 8) & 0xFF] & 0xFF) << 8 ^ \
|
||||
(Rijndael.S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^ \
|
||||
(Rijndael.S[(tt >> 24) & 0xFF] & 0xFF) << 24
|
||||
for i in xrange(KC / 2 + 1, KC):
|
||||
tk[i] ^= tk[i-1]
|
||||
# copy values into round key arrays
|
||||
j = 0
|
||||
while j < KC and t < ROUND_KEY_COUNT:
|
||||
Ke[t / BC][t % BC] = tk[j]
|
||||
Kd[ROUNDS - (t / BC)][t % BC] = tk[j]
|
||||
j += 1
|
||||
t += 1
|
||||
# inverse MixColumn where needed
|
||||
for r in xrange(1, ROUNDS):
|
||||
for j in xrange(BC):
|
||||
tt = Kd[r][j]
|
||||
Kd[r][j] = Rijndael.U1[(tt >> 24) & 0xFF] ^ \
|
||||
Rijndael.U2[(tt >> 16) & 0xFF] ^ \
|
||||
Rijndael.U3[(tt >> 8) & 0xFF] ^ \
|
||||
Rijndael.U4[ tt & 0xFF]
|
||||
self.Ke = Ke
|
||||
self.Kd = Kd
|
||||
|
||||
def encrypt(self, plaintext):
|
||||
if len(plaintext) != self.block_size:
|
||||
raise ValueError('wrong block length, expected ' + str(self.block_size) + ' got ' + str(len(plaintext)))
|
||||
Ke = self.Ke
|
||||
|
||||
BC = self.block_size / 4
|
||||
ROUNDS = len(Ke) - 1
|
||||
if BC == 4:
|
||||
Rijndael.SC = 0
|
||||
elif BC == 6:
|
||||
Rijndael.SC = 1
|
||||
else:
|
||||
Rijndael.SC = 2
|
||||
s1 = Rijndael.shifts[Rijndael.SC][1][0]
|
||||
s2 = Rijndael.shifts[Rijndael.SC][2][0]
|
||||
s3 = Rijndael.shifts[Rijndael.SC][3][0]
|
||||
a = [0] * BC
|
||||
# temporary work array
|
||||
t = []
|
||||
# plaintext to ints + key
|
||||
for i in xrange(BC):
|
||||
t.append((ord(plaintext[i * 4 ]) << 24 |
|
||||
ord(plaintext[i * 4 + 1]) << 16 |
|
||||
ord(plaintext[i * 4 + 2]) << 8 |
|
||||
ord(plaintext[i * 4 + 3]) ) ^ Ke[0][i])
|
||||
# apply round transforms
|
||||
for r in xrange(1, ROUNDS):
|
||||
for i in xrange(BC):
|
||||
a[i] = (Rijndael.T1[(t[ i ] >> 24) & 0xFF] ^
|
||||
Rijndael.T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^
|
||||
Rijndael.T3[(t[(i + s2) % BC] >> 8) & 0xFF] ^
|
||||
Rijndael.T4[ t[(i + s3) % BC] & 0xFF] ) ^ Ke[r][i]
|
||||
t = copy.copy(a)
|
||||
# last round is special
|
||||
result = []
|
||||
for i in xrange(BC):
|
||||
tt = Ke[ROUNDS][i]
|
||||
result.append((Rijndael.S[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
|
||||
result.append((Rijndael.S[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
|
||||
result.append((Rijndael.S[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
|
||||
result.append((Rijndael.S[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF)
|
||||
return string.join(map(chr, result), '')
|
||||
|
||||
def decrypt(self, ciphertext):
|
||||
if len(ciphertext) != self.block_size:
|
||||
raise ValueError('wrong block length, expected ' + str(self.block_size) + ' got ' + str(len(ciphertext)))
|
||||
Kd = self.Kd
|
||||
|
||||
BC = self.block_size / 4
|
||||
ROUNDS = len(Kd) - 1
|
||||
if BC == 4:
|
||||
Rijndael.SC = 0
|
||||
elif BC == 6:
|
||||
Rijndael.SC = 1
|
||||
else:
|
||||
Rijndael.SC = 2
|
||||
s1 = Rijndael.shifts[Rijndael.SC][1][1]
|
||||
s2 = Rijndael.shifts[Rijndael.SC][2][1]
|
||||
s3 = Rijndael.shifts[Rijndael.SC][3][1]
|
||||
a = [0] * BC
|
||||
# temporary work array
|
||||
t = [0] * BC
|
||||
# ciphertext to ints + key
|
||||
for i in xrange(BC):
|
||||
t[i] = (ord(ciphertext[i * 4 ]) << 24 |
|
||||
ord(ciphertext[i * 4 + 1]) << 16 |
|
||||
ord(ciphertext[i * 4 + 2]) << 8 |
|
||||
ord(ciphertext[i * 4 + 3]) ) ^ Kd[0][i]
|
||||
# apply round transforms
|
||||
for r in xrange(1, ROUNDS):
|
||||
for i in xrange(BC):
|
||||
a[i] = (Rijndael.T5[(t[ i ] >> 24) & 0xFF] ^
|
||||
Rijndael.T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^
|
||||
Rijndael.T7[(t[(i + s2) % BC] >> 8) & 0xFF] ^
|
||||
Rijndael.T8[ t[(i + s3) % BC] & 0xFF] ) ^ Kd[r][i]
|
||||
t = copy.copy(a)
|
||||
# last round is special
|
||||
result = []
|
||||
for i in xrange(BC):
|
||||
tt = Kd[ROUNDS][i]
|
||||
result.append((Rijndael.Si[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
|
||||
result.append((Rijndael.Si[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
|
||||
result.append((Rijndael.Si[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
|
||||
result.append((Rijndael.Si[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF)
|
||||
return string.join(map(chr, result), '')
|
||||
|
||||
# @staticmethod
|
||||
# def encrypt_block(key, block):
|
||||
# return Rijndael(key, len(block)).encrypt(block)
|
||||
|
||||
# @staticmethod
|
||||
# def decrypt_block(key, block):
|
||||
# return Rijndael(key, len(block)).decrypt(block)
|
||||
|
||||
@staticmethod
|
||||
def test():
|
||||
def t(kl, bl):
|
||||
b = 'b' * bl
|
||||
r = Rijndael('a' * kl, bl)
|
||||
x = r.encrypt(b)
|
||||
assert x != b
|
||||
assert r.decrypt(x) == b
|
||||
t(16, 16)
|
||||
t(16, 24)
|
||||
t(16, 32)
|
||||
t(24, 16)
|
||||
t(24, 24)
|
||||
t(24, 32)
|
||||
t(32, 16)
|
||||
t(32, 24)
|
||||
t(32, 32)
|
||||
# Rijndael
|
||||
#############################################################################
|
||||
|
||||
key = open('key.bin', 'rb').read()
|
||||
plaintext = open('plaintext.bin', 'rb').read()
|
||||
while len(plaintext) % 16 != 0:
|
||||
plaintext = plaintext + b'\0'
|
||||
r = Rijndael(key, block_size = 16)
|
||||
ciphertext = b''
|
||||
for i in range(0, len(plaintext), 16):
|
||||
c = bytes(r.encrypt(plaintext[i:i+16]))
|
||||
ciphertext = ciphertext + c
|
||||
f = open('ciphertext.bin', 'wb')
|
||||
f.write(bytes(ciphertext))
|
||||
f.close()
|
||||
|
||||
cipertext = open('ciphertext.bin', 'rb').read()
|
||||
while len(ciphertext) % 16 != 0:
|
||||
ciphertext = ciphertext + b'\0'
|
||||
plaintext = b''
|
||||
for i in range(0, len(ciphertext), 16):
|
||||
p = r.decrypt(ciphertext[i:i+16])
|
||||
plaintext = plaintext + p
|
||||
f = open('plaintext-backatyou.bin', 'wb')
|
||||
f.write(bytes(plaintext))
|
||||
f.close()
|
||||
print('Done.')
|
||||
BIN
hw1.2/commontarball/rsaattack.pdf
Normal file
BIN
hw1.2/commontarball/rsaattack.pdf
Normal file
Binary file not shown.
53
hw1.2/commontarball/src/README.txt
Normal file
53
hw1.2/commontarball/src/README.txt
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
cse468encrypt.py is used for caesar and julia ciphers for Homeworks 1.2 and
|
||||
1.3.
|
||||
|
||||
|
||||
The rest are sample files to try out how the RSA and AES encryptions work for
|
||||
Homework 1.4. The recommended usage of this is to use your own loopback IP
|
||||
(127.0.0.1) in two terminal windows (so you can see in I/O of the server and
|
||||
client).
|
||||
|
||||
In addition, the serverPublicKey is the *actual* public key used in the lab, so
|
||||
that's the one the attacker used in the actual attack.
|
||||
|
||||
|
||||
File | Description |
|
||||
-----------------+------------------------------------------------------------+
|
||||
aes.py | Very basic classes for interfacing with AES and RSA |
|
||||
rsa.py | methods |
|
||||
-----------------+------------------------------------------------------------+
|
||||
key.pub | A sample public key |
|
||||
-----------------+------------------------------------------------------------+
|
||||
key | A sample private key |
|
||||
-----------------+------------------------------------------------------------+
|
||||
sample_client.py | A client that encrypts the AES key and the word "True" and |
|
||||
| sends it to the server |
|
||||
-----------------+------------------------------------------------------------+
|
||||
sample_server.py | A server that listens for messages from the client, |
|
||||
| decrypts the client's message, capitalizes the plaintext, |
|
||||
| and returns an encrypted version |
|
||||
-----------------+------------------------------------------------------------+
|
||||
serverPublicKey | The public key used by the true server for the lab |
|
||||
-----------------+------------------------------------------------------------+
|
||||
README.txt | This README |
|
||||
-----------------+------------------------------------------------------------+
|
||||
|
||||
|
||||
The python files should be run using python3, and you may need to install some
|
||||
python packages depending on your environment, like:
|
||||
|
||||
pip3 install pycrypto
|
||||
|
||||
You can run the programs in the following way from the terminal:
|
||||
$ python3 sample_server.py -p 10047 -kp key.pub -ks key
|
||||
$ python3 sample_client.py -ip 127.0.0.1 -p 10047 -f key.pub
|
||||
|
||||
The first call stands up the server that listens on the specified port (10047
|
||||
in this example). The -kp flag is the public key you'd like the server to use,
|
||||
and -ks is the private key.
|
||||
|
||||
The second call kicks off a client on the loopback at the same port with -f
|
||||
specifying the shared public key of the server.
|
||||
|
||||
|
||||
20
hw1.2/commontarball/src/aes.py
Normal file
20
hw1.2/commontarball/src/aes.py
Normal file
@ -0,0 +1,20 @@
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
|
||||
class AESCipher:
|
||||
|
||||
def __init__(self, key):
|
||||
self.key = key
|
||||
|
||||
def encrypt(self, raw):
|
||||
cipher = AES.new(self.key, AES.MODE_ECB)
|
||||
if len(raw) % 16 != 0:
|
||||
raw += ' ' * (16 - (len(raw) % 16))
|
||||
return cipher.encrypt(raw)
|
||||
|
||||
def decrypt(self, enc):
|
||||
cipher = AES.new(self.key, AES.MODE_ECB)
|
||||
overflow = len(enc) % 16
|
||||
if overflow != 0:
|
||||
enc += b' ' * (16 - overflow)
|
||||
return cipher.decrypt(enc)
|
||||
132
hw1.2/commontarball/src/attack_jed.py
Normal file
132
hw1.2/commontarball/src/attack_jed.py
Normal file
@ -0,0 +1,132 @@
|
||||
import argparse
|
||||
import os
|
||||
import time
|
||||
import socket
|
||||
import sys
|
||||
from aes import AESCipher
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Util.number import bytes_to_long
|
||||
from Crypto.Util.number import long_to_bytes
|
||||
import textwrap
|
||||
|
||||
def wrap64(string):
|
||||
return '\n'.join(textwrap.wrap(string,64))
|
||||
|
||||
# Handle command-line arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-ip", "--ipaddress",
|
||||
help='ip address where the server is running',
|
||||
default='127.0.0.1', # Defaults to loopback
|
||||
required=True)
|
||||
parser.add_argument("-p", "--port",
|
||||
help='port where the server is listening on',
|
||||
required=True)
|
||||
parser.add_argument("-f", "--publickey",
|
||||
help='name of public key',
|
||||
default='serverPublicKey',
|
||||
required=False)
|
||||
parser.add_argument("-v", "--verbose",
|
||||
help="print out extra info to stdout",
|
||||
default='True',
|
||||
required=False)
|
||||
parser.add_argument("-e", "--eavesdrop",
|
||||
help="filename of eavesdrop",
|
||||
default='True',
|
||||
required=False)
|
||||
|
||||
args = parser.parse_args()
|
||||
f = open(args.eavesdrop, "rb")
|
||||
b = f.read()
|
||||
f.close()
|
||||
|
||||
# load server's public key
|
||||
serverPublicKeyFileName = args.publickey
|
||||
key = ""
|
||||
with open(serverPublicKeyFileName, 'r') as f:
|
||||
key = RSA.importKey(f.read())
|
||||
|
||||
MESSAGE_LENGTH = 2048
|
||||
|
||||
# 256 byte RSA-encrypted AES key from client-server Wireshark capture for default 'True' message
|
||||
eavesdroppedrsa = b[0:256] #bytearray.fromhex('4a04ac1ffcc305c4c5f0daaeca07bca5be7cc795f812bd57d96933904ec4433d5033bae1729a6e0fae3d62cc081ed51111db6cfe96b2d84c633c827662bc076c83d401bbbb02a0d454b6fb6ab355be62e9dec8542741f2583b49d0794230ffdcdc6aebf444e139f69594cd4cfdc544178611027757cf534c725384a0e35b2eee66772261bc49de4666f9cb16b94e32335cce727664032058259a6ff6e31a110f4f8c03f1ec166a656269c1a126a587d4e472cc082bd08df6c50b2567e29798c84f7abd605aef66a46fdb471c5bad7c02071923a210bbfe236e5a5b32359d12040a37c9db2785f1d11faa2619b617b6deeb7da0011fbba82e44246aac99231d42')
|
||||
|
||||
|
||||
bitsknown = ''
|
||||
while (len(bitsknown) < 256):
|
||||
i = 255 - len(bitsknown)
|
||||
shifty = pow(2, i * key.e, key.n)
|
||||
sessionkey = (bytes_to_long(eavesdroppedrsa) * shifty) % key.n
|
||||
for tryabit in ['0', '1']:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
hint = (i << 1) + int(tryabit)
|
||||
print(hint)
|
||||
#sock.setsockopt(socket.SOL_TCP, socket.TCP_MAXSEG, 500 + hint)
|
||||
sock.setsockopt(socket.SOL_IP, socket.IP_TTL, hint % 128 + 32)
|
||||
differentipaddress = "127.0.0." + str((hint >> 7) + 1)
|
||||
print(differentipaddress)
|
||||
server_address = (differentipaddress, int(args.port))
|
||||
#server_address = (args.ipaddress, int(args.port))
|
||||
sock.connect(server_address)
|
||||
sock.settimeout(2)
|
||||
AESkeytry = long_to_bytes(int(tryabit + bitsknown + '0'*i, 2), 32)
|
||||
print('guessing...\n{}'.format(wrap64(tryabit + bitsknown + '0'*i)))
|
||||
aes = AESCipher(AESkeytry)
|
||||
answer = b''
|
||||
try:
|
||||
message = aes.encrypt('GoSeeCal')
|
||||
msg = long_to_bytes(sessionkey, 256) + message
|
||||
sock.sendall(msg)
|
||||
amount_received = 0
|
||||
amount_expected = len(message)
|
||||
|
||||
if amount_expected % 16 != 0:
|
||||
amount_expected += (16 - (len(message) % 16))
|
||||
|
||||
if amount_expected > amount_received:
|
||||
while amount_received < amount_expected:
|
||||
data = sock.recv(MESSAGE_LENGTH)
|
||||
amount_received += len(data)
|
||||
answer += data
|
||||
except Exception as e:
|
||||
print(e)
|
||||
else:
|
||||
#messageresult = (aes.decrypt(answer))
|
||||
if aes.decrypt(answer).strip() == b'GOSEECAL':
|
||||
bitsknown = str(tryabit) + bitsknown
|
||||
break
|
||||
finally:
|
||||
sock.close()
|
||||
|
||||
AESkey = long_to_bytes(int(bitsknown, 2), 32)
|
||||
aes = AESCipher(AESkey)
|
||||
eavesdroppedaes = b[256:] #bytes.fromhex('088d72fda25863ae81a27ddc286ee8ffef55bdcd0eeee4487fa42cb9c012155e6c38a32d741c68aaa86fda4c9878cbb4')
|
||||
print('Recovered plaintext is: {}'.format(aes.decrypt(eavesdroppedaes)))
|
||||
print('Sending to server...')
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
server_address = (args.ipaddress, int(args.port))
|
||||
sock.connect(server_address)
|
||||
sock.settimeout(2)
|
||||
aes = AESCipher(AESkey)
|
||||
answer = b''
|
||||
sessionkey = bytes_to_long(eavesdroppedrsa)
|
||||
try:
|
||||
message = eavesdroppedaes
|
||||
msg = long_to_bytes(sessionkey, 256) + message
|
||||
sock.sendall(msg)
|
||||
amount_received = 0
|
||||
amount_expected = len(message)
|
||||
|
||||
if amount_expected % 16 != 0:
|
||||
amount_expected += (16 - (len(message) % 16))
|
||||
|
||||
if amount_expected > amount_received:
|
||||
while amount_received < amount_expected:
|
||||
data = sock.recv(MESSAGE_LENGTH)
|
||||
amount_received += len(data)
|
||||
answer += data
|
||||
except Exception as e:
|
||||
print(e)
|
||||
else:
|
||||
print(aes.decrypt(answer).strip())
|
||||
finally:
|
||||
sock.close()
|
||||
94
hw1.2/commontarball/src/cse468encrypt.py
Normal file
94
hw1.2/commontarball/src/cse468encrypt.py
Normal file
@ -0,0 +1,94 @@
|
||||
import argparse
|
||||
import os
|
||||
import time
|
||||
#import socket
|
||||
import sys
|
||||
import string
|
||||
#from aes import AESCipher
|
||||
#from Crypto.PublicKey import RSA
|
||||
|
||||
# Handle command-line arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-c", "--cipher",
|
||||
help='cipher... caesar or julia',
|
||||
required=True)
|
||||
parser.add_argument("-d", "--decrypt",
|
||||
help='Decrypt a file',
|
||||
required=False)
|
||||
parser.add_argument("-e", "--encrypt",
|
||||
help='Encrypt a file',
|
||||
required=False)
|
||||
parser.add_argument("-o", "--outfile",
|
||||
help='Output file',
|
||||
required=False)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
encrypting = True
|
||||
|
||||
def lrot(n, d): return ((n << d)|(n >> (8 - d)))&0xff
|
||||
|
||||
try:
|
||||
ciphertext = open(args.decrypt, "rb").read()
|
||||
try:
|
||||
plaintext = open(args.encrypt, "rb").read()
|
||||
print("You can't specify both -e and -d")
|
||||
exit(1)
|
||||
except:
|
||||
encrypting = False
|
||||
except:
|
||||
try:
|
||||
plaintext = open(args.encrypt, "rb").read()
|
||||
except:
|
||||
print("Input file error (did you specify -e or -d?)")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
whichcipher = args.cipher
|
||||
if (whichcipher == 'julia') or (whichcipher == 'caesar'):
|
||||
output = open(args.outfile, "wb")
|
||||
else:
|
||||
print('Available ciphers are julia and caesar, case sensitive')
|
||||
exit(1)
|
||||
except:
|
||||
print("Output file error or you didn't specify cipher")
|
||||
exit(1)
|
||||
|
||||
|
||||
|
||||
if (encrypting):
|
||||
if whichcipher == 'julia':
|
||||
keybytes = bytes(os.urandom(13))
|
||||
keyshift = keybytes[0] % 7 + 1
|
||||
keyxor = []
|
||||
keyxorasstring = ""
|
||||
for i in range(1, 13):
|
||||
keyxor.append(ord(string.ascii_letters[keybytes[i] % len(string.ascii_letters)]))
|
||||
keyxorasstring = keyxorasstring + chr(keyxor[i-1])
|
||||
print('Key is shifting by ' + str(keyshift) + ' and XORing with ' + keyxorasstring)
|
||||
ciphertext = []
|
||||
for i in range(0, len(plaintext)):
|
||||
ciphertext.append(lrot(plaintext[i], keyshift) ^ keyxor[i % len(keyxor)])
|
||||
output.write(bytes(ciphertext))
|
||||
output.close
|
||||
elif whichcipher == 'caesar':
|
||||
keybytes = bytes(os.urandom(1))
|
||||
keyrotate = int(keybytes[0] % 25) + 1
|
||||
print('Key is ' + string.ascii_uppercase[keyrotate] + ' i.e. rotating by ' + str(keyrotate))
|
||||
skipped = 0
|
||||
ciphertext = ''
|
||||
for i in range(0, len(plaintext)):
|
||||
if chr(plaintext[i]) in string.ascii_uppercase:
|
||||
p = plaintext[i] - ord('A')
|
||||
c = chr(ord('A') + ((p + keyrotate) % 26))
|
||||
ciphertext = ciphertext + c
|
||||
else:
|
||||
skipped = skipped + 1
|
||||
output.write(ciphertext.encode('ascii'))
|
||||
output.close
|
||||
if skipped != 0:
|
||||
print('Skipped ' + str(skipped) + ' bytes for not being capital letters')
|
||||
else:
|
||||
print('Should not have gotten here')
|
||||
exit(1)
|
||||
|
||||
9
hw1.2/commontarball/src/key.pub
Normal file
9
hw1.2/commontarball/src/key.pub
Normal file
@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr7GLK94LlBt4NvvzaiAb
|
||||
YWrDeY6A0Bpmu92p2ZrYskKDKCMDGalJGX8bDS7eRTd2yiTu0tT5xdF/awv1Aeaw
|
||||
vUszJdLCbN8oFOT/8XUho6qpGPeX1iVtEA0B1oa7TD8nIshV7d4lMqP41I5FED6w
|
||||
R5fndVGE2ajRdS5yDZB+Mujyqpnl1vwHXxc1gm+shR2zpEO3fbuW/KI1TeO08aYC
|
||||
OmLnAWZtNU0n4pIsupu1WMc2MGZh+zu6Hg+6gRhbB8NLXHC//lxIwYmnNjieIJu5
|
||||
o0zP3KNxp0pNzwtGJqi1z9Rr42l+lTXrOTlcfYXAeML83agjUbUuavfDwLjlthMC
|
||||
swIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
36
hw1.2/commontarball/src/rsa.py
Normal file
36
hw1.2/commontarball/src/rsa.py
Normal file
@ -0,0 +1,36 @@
|
||||
from Crypto.PublicKey import RSA
|
||||
|
||||
|
||||
class RSACipher:
|
||||
|
||||
def __init__(self, publicKeyFileName, privateKeyFileName):
|
||||
"""
|
||||
Generate a RSA key pair for server
|
||||
"""
|
||||
try:
|
||||
f = open(privateKeyFileName, 'rb')
|
||||
self.keys = RSA.importKey(f.read())
|
||||
except FileNotFoundError:
|
||||
self.keys = RSA.generate(2048)
|
||||
self.publickey = self.keys.publickey()
|
||||
# export public and private keys
|
||||
privHandle = open(privateKeyFileName, 'wb')
|
||||
privHandle.write(self.keys.exportKey('PEM'))
|
||||
privHandle.close()
|
||||
|
||||
pubHandle = open(publicKeyFileName, 'wb')
|
||||
pubHandle.write(self.keys.publickey().exportKey())
|
||||
pubHandle.close()
|
||||
self.publickey = self.keys.publickey()
|
||||
|
||||
def decrypt(self, ciphertext):
|
||||
"""-
|
||||
Decrypt a ciphertext
|
||||
"""
|
||||
return self.keys.decrypt(ciphertext)
|
||||
|
||||
def encrypt(self, message):
|
||||
"""
|
||||
Encrypt a message
|
||||
"""
|
||||
return self.publickey.encrypt(message, 32)
|
||||
124
hw1.2/commontarball/src/sample_client.py
Normal file
124
hw1.2/commontarball/src/sample_client.py
Normal file
@ -0,0 +1,124 @@
|
||||
import argparse
|
||||
import os
|
||||
import time
|
||||
import socket
|
||||
import sys
|
||||
from aes import AESCipher
|
||||
from Crypto.PublicKey import RSA
|
||||
|
||||
# Handle command-line arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-ip", "--ipaddress",
|
||||
help='ip address where the server is running',
|
||||
default='127.0.0.1', # Defaults to loopback
|
||||
required=True)
|
||||
parser.add_argument("-p", "--port",
|
||||
help='port where the server is listening on',
|
||||
required=True)
|
||||
parser.add_argument("-f", "--publickey",
|
||||
help='name of public key',
|
||||
default='serverPublicKey',
|
||||
required=False)
|
||||
parser.add_argument("-v", "--verbose",
|
||||
help="print out extra info to stdout",
|
||||
default='True',
|
||||
required=False)
|
||||
parser.add_argument("-m", "--messagefile",
|
||||
help='what file the message should come from',
|
||||
default='',
|
||||
required=True)
|
||||
parser.add_argument("-e", "--eavesdrop",
|
||||
help='where to put eavesdropped stuff',
|
||||
default='',
|
||||
required=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Create a TCP/IP socket
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
# Connect the socket to the port where the server is listening
|
||||
server_address = (args.ipaddress, int(args.port))
|
||||
sock.connect(server_address)
|
||||
sock.settimeout(2)
|
||||
|
||||
AESKey = bytes(os.urandom(32))
|
||||
while AESKey[0] == 0: # Make sure there aren't leading 0s
|
||||
AESKey = bytes(os.urandom(32))
|
||||
|
||||
if args.verbose is True:
|
||||
binKey = bin(int.from_bytes(AESKey, byteorder='big'))
|
||||
print("Using AES key : {}".format(binKey))
|
||||
|
||||
# load server's public key
|
||||
serverPublicKeyFileName = args.publickey
|
||||
key = ""
|
||||
with open(serverPublicKeyFileName, 'r') as f:
|
||||
key = RSA.importKey(f.read())
|
||||
|
||||
MESSAGE_LENGTH = 2048
|
||||
|
||||
encryptedKey = key.encrypt(AESKey, 32)[0]
|
||||
while len(encryptedKey) != 2048>>3:
|
||||
#Python is weird about leading 0's, fix it up
|
||||
encryptedKey = b'\x00' + encryptedKey
|
||||
aes = AESCipher(AESKey)
|
||||
try:
|
||||
# Send data
|
||||
try:
|
||||
filetosend = open(args.messagefile, "r")
|
||||
plaintext = filetosend.read()
|
||||
filetosend.close()
|
||||
print(plaintext)
|
||||
message = aes.encrypt(plaintext)
|
||||
except ValueError:
|
||||
print("Client with port {} failed.".format(args.port),
|
||||
file=sys.stderr)
|
||||
exit(1)
|
||||
fileforeavesdrop = open(args.eavesdrop, "wb")
|
||||
msg = bytearray(encryptedKey + message)
|
||||
# msg: AES key encrypted by the public key of RSA
|
||||
# + message encrypted by the AES key
|
||||
|
||||
print('Sending: {}'.format(message.hex()))
|
||||
sock.sendall(msg)
|
||||
fileforeavesdrop.write(msg)
|
||||
fileforeavesdrop.close()
|
||||
|
||||
# Look for the response
|
||||
amount_received = 0
|
||||
amount_expected = len(message)
|
||||
|
||||
# if amount_expected % 16 != 0:
|
||||
# amount_expected += (16 - (len(message) % 16))
|
||||
|
||||
answer = b''
|
||||
if amount_expected > amount_received:
|
||||
while amount_received < amount_expected:
|
||||
try:
|
||||
data = sock.recv(MESSAGE_LENGTH)
|
||||
print(data)
|
||||
except socket.timeout as e:
|
||||
err = e.args[0]
|
||||
|
||||
if err == 'timed out':
|
||||
print('Connection timed out, waiting for retry',
|
||||
file=sys.stderr)
|
||||
time.sleep(1)
|
||||
continue
|
||||
else:
|
||||
print('Another issue: {}'.format(e),
|
||||
file=sys.stderr)
|
||||
break
|
||||
except socket.error as e:
|
||||
print('Socket error: {}'.format(e),
|
||||
file=sys.stderr)
|
||||
break
|
||||
amount_received += len(data)
|
||||
answer += data
|
||||
|
||||
print('Received: {}'.format(aes.decrypt(answer)))
|
||||
print('Succeeded for ' + args.messagefile)
|
||||
|
||||
finally:
|
||||
sock.close()
|
||||
106
hw1.2/commontarball/src/sample_server.py
Normal file
106
hw1.2/commontarball/src/sample_server.py
Normal file
@ -0,0 +1,106 @@
|
||||
import argparse
|
||||
import os
|
||||
import socket
|
||||
from time import sleep
|
||||
from rsa import RSACipher
|
||||
from aes import AESCipher
|
||||
import binascii
|
||||
import string
|
||||
|
||||
|
||||
def getSessionKey(rsa, cipher):
|
||||
"""
|
||||
Get the AES session key be decrypting the RSA ciphertext
|
||||
"""
|
||||
AESEncrypted = cipher[:256]
|
||||
print('AESEncrypted...')
|
||||
print(binascii.hexlify(AESEncrypted))
|
||||
AESKey = rsa.decrypt(AESEncrypted)
|
||||
return AESKey[(len(AESKey)-32):]
|
||||
|
||||
|
||||
def myDecrypt(rsa, cipher):
|
||||
"""
|
||||
Decrypt the client message:
|
||||
AES key encrypted by the
|
||||
public RSA key of the server + message encrypted by the AES key
|
||||
"""
|
||||
messageEncrypted = cipher[256:]
|
||||
print('messageEncrypted...')
|
||||
print(binascii.hexlify(messageEncrypted))
|
||||
AESKey = getSessionKey(rsa, cipher)
|
||||
aes = AESCipher(AESKey)
|
||||
return aes.decrypt(messageEncrypted)
|
||||
|
||||
|
||||
def handle_client(sock, rsa):
|
||||
print('Waiting for a connection...') # Wait for a conneciton
|
||||
connection, client_address = sock.accept()
|
||||
|
||||
try:
|
||||
# Receive the data
|
||||
print("Recieving....")
|
||||
cipher = connection.recv(2048)
|
||||
print("Message Received...")
|
||||
|
||||
try:
|
||||
message = myDecrypt(rsa, cipher)
|
||||
print("Received as: {}".format(message))
|
||||
#if not message.decode('utf-8').strip().isprintable():
|
||||
# raise Exception("Not printable?")
|
||||
aes = AESCipher(getSessionKey(rsa, cipher))
|
||||
msg = aes.encrypt(message.upper())
|
||||
except:
|
||||
connection.sendall("Couldn't decrypt!".encode('utf-8'))
|
||||
else:
|
||||
print('decrypted msg is {}'.format(aes.decrypt(msg)))
|
||||
print('message is {}'.format(message))
|
||||
connection.sendall(msg)
|
||||
finally:
|
||||
# Clean up the connection
|
||||
connection.close()
|
||||
return True
|
||||
|
||||
|
||||
# Main routine starts here
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-p", "--port",
|
||||
help='starting port where the server is listening on',
|
||||
required=True)
|
||||
parser.add_argument("-kp", "--publickey",
|
||||
help='the public key for the server',
|
||||
default='serverPublicKey',
|
||||
required=False)
|
||||
parser.add_argument("-ks", "--privatekey",
|
||||
help='the private key for the server',
|
||||
default='privateKey.pem',
|
||||
required=False)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
port = int(args.port)
|
||||
server_address = ('0.0.0.0', port)
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
|
||||
# Bind socket to port
|
||||
try:
|
||||
sock.bind(server_address)
|
||||
except OSError:
|
||||
print('Address {} already in use'.format(server_address))
|
||||
|
||||
# Listen for incoming connections
|
||||
sock.listen(10)
|
||||
|
||||
#pid = os.fork()
|
||||
|
||||
#if pid == 0:
|
||||
rsa = RSACipher(publicKeyFileName=args.publickey,
|
||||
privateKeyFileName=args.privatekey)
|
||||
|
||||
while True:
|
||||
finished = handle_client(sock, rsa)
|
||||
if finished is True:
|
||||
print("Processed client message on port {}".format(port))
|
||||
#sleep(1)
|
||||
64
hw1.2/commontarball/streamy.py
Normal file
64
hw1.2/commontarball/streamy.py
Normal file
@ -0,0 +1,64 @@
|
||||
# pip3 install pyshark
|
||||
# Then ...
|
||||
# python3 streamy.py mypcap.pcap | python3 buildkey.py
|
||||
|
||||
import pyshark
|
||||
import sys
|
||||
|
||||
# open the pcap file, filtered for a single TCP stream
|
||||
cap = pyshark.FileCapture(sys.argv[1])
|
||||
|
||||
tupledict = {}
|
||||
datadict = {}
|
||||
longeststreamlen = -1
|
||||
skippy = -1
|
||||
|
||||
for p in cap:
|
||||
if p.transport_layer == 'TCP':
|
||||
stream = p.tcp.stream
|
||||
if (int(p.tcp.dstport) == 10047):
|
||||
try:
|
||||
thisstream = p.data.data.binary_value
|
||||
if (len(thisstream) > longeststreamlen):
|
||||
longeststream = thisstream[256:]
|
||||
longeststreamlen = len(thisstream)
|
||||
skippy = stream
|
||||
except AttributeError: # Skip the ACKs.
|
||||
pass
|
||||
#if (stream not in tupledict and
|
||||
if(int(p.tcp.dstport) == 10047):
|
||||
try:
|
||||
tupledict[stream] = (p.ip.dst, p.ip.ttl)
|
||||
except AttributeError: # Skip the ACKs.
|
||||
pass
|
||||
#if (stream not in datadict and
|
||||
if(int(p.tcp.srcport) == 10047):
|
||||
try:
|
||||
#if (int(stream) == 190):
|
||||
# print("PING")
|
||||
datadict[stream] = p.data.data.binary_value
|
||||
#if (int(stream) == 190):
|
||||
# print("PONG")
|
||||
except AttributeError as error: # Skip the ACKs.
|
||||
#if (int(stream) == 190):
|
||||
# print(error)
|
||||
#val=p.all_fields
|
||||
datadict[stream] = b'hello'
|
||||
#print(val)
|
||||
pass
|
||||
|
||||
print(longeststream.hex())
|
||||
|
||||
for packettuple in tupledict:
|
||||
hinttuple = tupledict[packettuple]
|
||||
if (packettuple in datadict):
|
||||
if (packettuple != skippy):
|
||||
if (datadict[packettuple] != b"Couldn't decrypt!"):
|
||||
print(hinttuple[0][8:] + " " + hinttuple[1])
|
||||
else:
|
||||
#pass
|
||||
print("Something was in tupledict but not datadict")
|
||||
print("Stream is " + str(int(packettuple)))
|
||||
exit(1)
|
||||
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import sys
|
||||
import os
|
||||
from itertools import cycle
|
||||
import gzip
|
||||
@ -8,30 +7,27 @@ def ror(n, rotations, width):
|
||||
return (2**width - 1) & (n >> rotations | n << (width - rotations))
|
||||
|
||||
|
||||
def rol(n, rotations, width):
|
||||
return (2**width - 1) & (n << rotations | n >> (width - rotations))
|
||||
|
||||
|
||||
with open("3/withkey/juliakey.txt", "r") as julia_key_file, open(
|
||||
"3/withkey/juliaplaintext.txt.gz.enc", "rb"
|
||||
) as julia_cipher_file:
|
||||
julia_key_content = julia_key_file.read()
|
||||
key_shift = int(julia_key_content.split()[4])
|
||||
key_xor = julia_key_content.split()[-1]
|
||||
print("key shift", key_shift)
|
||||
print("key xor", key_xor)
|
||||
|
||||
julia_cipher_content = julia_cipher_file.read()
|
||||
result = bytes()
|
||||
for c_byte, k_byte in zip(julia_cipher_content, cycle(key_xor)):
|
||||
tmp = c_byte ^ ord(k_byte)
|
||||
# kinda misleading, question mentions that encryption rotates bits but didn't mention which direction
|
||||
# imagine spending 3 hours thinking it's gzip when it turns out you rotate RIGHT
|
||||
result += ror(c_byte ^ ord(k_byte), 1, 8).to_bytes(1, "big")
|
||||
|
||||
# gzip - write as bytes, read with decompression
|
||||
with open("test.gz", "wb") as f:
|
||||
f.write(result)
|
||||
with gzip.open("test.gz", "r") as gf:
|
||||
print("answer starts here-----"+gf.read().decode()+"-----ends here")
|
||||
os.remove("test.gz")
|
||||
|
||||
key_shift = int(julia_key_content.split()[4])
|
||||
key_xor = julia_key_content.split()[-1]
|
||||
print("key shift", key_shift)
|
||||
print("key xor", key_xor)
|
||||
|
||||
result = bytes()
|
||||
for c_byte, k_byte in zip(julia_cipher_content, cycle(key_xor)):
|
||||
tmp = c_byte ^ ord(k_byte)
|
||||
# kinda dumb tangent: question mentions that encryption rotates bits but didn't mention which direction
|
||||
# imagine spending 3 hours thinking the problem is gzip when it turns out you rotate RIGHT, not left
|
||||
result += ror(tmp, 1, 8).to_bytes(1, "big")
|
||||
|
||||
# gzip - write as bytes, read with decompression
|
||||
with open("test.gz", "wb") as f:
|
||||
f.write(result)
|
||||
with gzip.open("test.gz", "r") as gf:
|
||||
print("answer starts here-----" + gf.read().decode() + "-----ends here")
|
||||
os.remove("test.gz")
|
||||
|
||||
68
hw1.2/julia_without_key.py
Normal file
68
hw1.2/julia_without_key.py
Normal file
@ -0,0 +1,68 @@
|
||||
import sys
|
||||
import os
|
||||
from itertools import cycle
|
||||
import gzip
|
||||
|
||||
|
||||
def ror(n, rotations, width):
|
||||
return (2**width - 1) & (n >> rotations | n << (width - rotations))
|
||||
|
||||
|
||||
with open("3/withoutkey/secretfile.txt.gz.enc", "rb") as julia_cipher_file:
|
||||
julia_cipher_content = julia_cipher_file.read()
|
||||
|
||||
# ASSUMPTION: gzip used with FNAME or FCOMMENT flag, and encodes the (known) filename after the initial 10-byte header
|
||||
# if not, strat breaks down
|
||||
filename = "secretfile.txt"
|
||||
filename_bytes = filename.encode()
|
||||
filename_bytes_enc = julia_cipher_content[10 : 10 + len(filename)]
|
||||
|
||||
# print("[+] Filename bytes:\t\t", filename_bytes.hex())
|
||||
# print("[+] Filename bytes, encrypted:\t", filename_bytes_enc.hex())
|
||||
|
||||
key_length = 12
|
||||
derived_rotation = 0
|
||||
derived_key_bytes = bytearray(key_length)
|
||||
|
||||
# filename is 14 characters, key length is 12, so key wraps around, allowing us to check rotation amount
|
||||
for byte in range(0, 256):
|
||||
possible_key_byte = bytes([byte])
|
||||
for possible_rotation in range(1, 8):
|
||||
if (
|
||||
ror(filename_bytes_enc[0] ^ possible_key_byte[0], possible_rotation, 8)
|
||||
== filename_bytes[0]
|
||||
and ror(
|
||||
filename_bytes_enc[key_length] ^ possible_key_byte[0],
|
||||
possible_rotation,
|
||||
8,
|
||||
)
|
||||
== filename_bytes[key_length]
|
||||
):
|
||||
derived_rotation = possible_rotation
|
||||
break
|
||||
else:
|
||||
continue
|
||||
break
|
||||
print("Rotation:", derived_rotation)
|
||||
|
||||
for idx in range(0, key_length):
|
||||
for byte in range(0, 256):
|
||||
possible_key_byte = bytes([byte])
|
||||
if (
|
||||
ror(filename_bytes_enc[idx] ^ possible_key_byte[0], derived_rotation, 8)
|
||||
== filename_bytes[idx]
|
||||
):
|
||||
derived_key_bytes[(idx + 10) % key_length] = possible_key_byte[0]
|
||||
break
|
||||
print("Key:", derived_key_bytes.hex())
|
||||
|
||||
result = bytes()
|
||||
for c_byte, k_byte in zip(julia_cipher_content, cycle(derived_key_bytes)):
|
||||
result += ror(c_byte ^ k_byte, derived_rotation, 8).to_bytes(1, sys.byteorder)
|
||||
|
||||
# gzip - write as bytes, read with decompression
|
||||
with open("test.gz", "wb") as f:
|
||||
f.write(result)
|
||||
with gzip.open("test.gz", "r") as gf:
|
||||
print("answer starts here-----" + gf.read().decode() + "-----ends here")
|
||||
os.remove("test.gz")
|
||||
Loading…
x
Reference in New Issue
Block a user