Created
December 9, 2015 20:57
-
-
Save tajo/f87fc8fdd23df7e42b62 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import binascii | |
import sys | |
import time | |
import base64 | |
from des import * | |
_pythonMajorVersion = sys.version_info[0] | |
def xor_bits(list1, list2): | |
res = [] | |
for i in xrange(0, len(list1)): | |
res.append(xor(list1[i], list2[i])) | |
return res | |
def xor(bit1, bit2): | |
if (bit1 == bit2): | |
return 0 | |
return 1 | |
def bitfield(n): | |
bits = [int(digit) for digit in bin(n)[2:]] | |
while(len(bits) < 8): | |
bits.insert(0, 0) | |
return bits | |
def hexToBits(iv): | |
bits = [] | |
for i in xrange(0, len(iv), 2): | |
bits += bitfield(int(iv[i] + iv[i+1], 16)) | |
return bits | |
def keyToStr(key): | |
bitKey = hexToBits(key) | |
keyStr = '' | |
for i in xrange(0, len(bitKey), 8): | |
keyStr += chr(int(str(bitKey[i]) + str(bitKey[i+1]) + str(bitKey[i+2]) | |
+ str(bitKey[i+3]) + str(bitKey[i+4]) + str(bitKey[i+5]) | |
+ str(bitKey[i+6]) + str(bitKey[i+7]) , 2)) | |
return keyStr | |
def strToBits(data): | |
if _pythonMajorVersion < 3: | |
data = [ord(c) for c in data] | |
l = len(data) * 8 | |
result = [0] * l | |
pos = 0 | |
for ch in data: | |
i = 7 | |
while i >= 0: | |
if ch & (1 << i) != 0: | |
result[pos] = 1 | |
else: | |
result[pos] = 0 | |
pos += 1 | |
i -= 1 | |
return result | |
def bitsToStr(data): | |
result = [] | |
pos = 0 | |
c = 0 | |
while pos < len(data): | |
c += data[pos] << (7 - (pos % 8)) | |
if (pos % 8) == 7: | |
result.append(c) | |
c = 0 | |
pos += 1 | |
if _pythonMajorVersion < 3: | |
return ''.join([ chr(c) for c in result ]) | |
else: | |
return bytes(result) | |
def cbc_encrypt(message, key, iv): | |
""" | |
Args: | |
message: string, bytes, cannot be unicode | |
key: string, bytes, cannot be unicode | |
Returns: | |
ciphertext: string | |
""" | |
# Message preprocessing & padding | |
bitMessage = strToBits(message) | |
bitMessage.append(1) | |
while len(bitMessage) % 64: | |
bitMessage.append(0) | |
# CBC | |
d = des(keyToStr(key)) | |
xorWith = hexToBits(iv) | |
cipher = [] | |
for i in xrange(0, len(bitMessage), 64): | |
xorWith = d.des_encrypt(xor_bits(xorWith, bitMessage[i:i+64])) | |
cipher += xorWith | |
return bitsToStr(cipher) | |
def cbc_decrypt(message, key, iv): | |
""" | |
Args: | |
message: string, bytes, cannot be unicode | |
key: string, bytes, cannot be unicode | |
Returns: | |
plaintext: string | |
""" | |
# decrypt CBC | |
bitMessage = hexToBits(binascii.hexlify(message)) | |
d = des(keyToStr(key)) | |
xorWith = hexToBits(iv) | |
plaintext = [] | |
for i in xrange(0, len(bitMessage), 64): | |
plaintext += xor_bits(xorWith, d.des_decrypt(bitMessage[i:i+64])) | |
xorWith = bitMessage[i:i+64] | |
# remove padding | |
while plaintext[len(plaintext)-1] == 0: | |
plaintext.pop() | |
plaintext.pop() | |
return bitsToStr(plaintext) | |
def main(argv): | |
if len(argv) != 5: | |
print 'Wrong number of arguments!\npython task1.py $MODE $INFILE $KEYFILE $IVFILE $OUTFILE' | |
sys.exit(1) | |
mode = argv[0] | |
infile = argv[1] | |
keyfile = argv[2] | |
ivfile = argv[3] | |
outfile = argv[4] | |
message = None | |
key = None | |
iv = None | |
try: | |
message = open(infile, 'r').read() | |
key = open(keyfile, 'r').read() | |
iv = open(ivfile, 'r').read() | |
except: | |
print 'File Not Found' | |
start = time.time() | |
if mode == "enc": | |
output = cbc_encrypt(message, key, iv) | |
elif mode == "dec": | |
output = cbc_decrypt(message, key, iv) | |
else: | |
print "Wrong mode!" | |
sys.exit(1) | |
end = time.time() | |
print "Consumed CPU time=%f"% (end - start) | |
open(outfile, 'w').write(output) | |
if __name__=="__main__": | |
main(sys.argv[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment