Government Security
Network Security Resources

Jump to content

Photo

[Python] Otep -- One-Time Encryption Program

- - - - - networking encryption network python ssh hash md5
  • Please log in to reply
No replies to this topic

#1 z3ros3c

z3ros3c

    Private

  • Members
  • 1 posts

Posted 24 May 2010 - 10:37 PM

Read a description of One-Time Pads here.

OTEP is a simple program I wrote in Python for file and stream encryption / decryption using One-Time Pads.

Feel free to suggest improvements to the code, or new ideas to implement. I've already got a few upgrades in mind (for example, using optparse instead of parsing options by hand), but I'd love to hear your input.

One feature I would like to add (but have not yet implemented) is networking -- e.g. set up a OTEP-encrypted network tunnel similar to SSH tunneling. If you can figure out a clean and efficient way of adding this, let me know! It would be nice to add this feature.

#!/usr/bin/env python

"""
OTEP (One-Time Encryption Pad) v2.0
(C)Copyright 2010.04.11 z3ros3c@gmail.com, All rights reserved.

This program generates one-time encryption pads, and can use them
to encrypt and decrypt files and piped input. The idea behind one-
time pads is that they are used once, and are nigh impossible to
crack without posessing the pad.
"""

import hashlib
from sys import argv,exit,stdin,stdout,stderr
from random import random
from os import unlink
from time import time

hash = lambda x: hashlib.md5(x).hexdigest()

usage = """Usage:
 otep -g (layers)
	Generate and save a pad.
 otep -e [filename] (pad)
	Encrypt a file, with or without a pad.
 otep -d [filename] [pad]
	Decrypt a file with a pad.
 otep -m [number] (layers)
	Mass-generate pads.
 otep -pe (pad)
	Encrypt a pipe, with or without a pad.
 otep -pd [pad]
	Decrypt a pipe with a pad.
"""

def shuffle(set):
 copy = set[:]
 for counter in range(len(copy) * 3):
	copy.append(copy.pop(int((random() * 100000) % len(copy))))
 return copy

def savepad(pad):
 stderr.write("Saving pad...")
 try:
	fullPad = []
	for row in pad:
 	fullPad += row
	output = bytearray(len(fullPad))
	for x in range(len(fullPad)):
 	output[x] = fullPad[x]
	fileName = hash(str(output))
	outFile = open(fileName,'wb')
	outFile.write(output)
	outFile.close()
	stderr.write("Pad saved as %s.\n" % (fileName))
 except:
	stderr.write("Could not save pad.\n")

def loadpad(fileName):
 stderr.write("Loading pad from file %s..." % (fileName))
 try:
	inFile = open(fileName,'rb')
	fullPad = bytearray(inFile.read())
	inFile.close()
	if (len(fullPad) % 256) != 0:
 	stderr.write("Invalid pad.\n")
 	return []
	layers = len(fullPad) / 256
	pad = []
	for counter in range(256):
 	pad.append([])
	for row in range(256):
 	for counter in range(layers):
 	pad[row].append(fullPad.pop(0))
	return sanitycheck(pad)
 except:
	stderr.write("Unable to load pad from %s.\n" % (fileName))
	return []

def sanitycheck(pad):
 for column in range(len(pad[0])):
	tmp = []
	for row in range(256):
 	if pad[row][column] in tmp:
 	stderr.write("Invalid pad.\n")
 	return []
 	tmp.append(pad[row][column])
 stderr.write("Pad checks good.\n")
 return pad

def genpad(length = 256):
 if length > 256:
	stderr.write("Defaulting to max layers -- 256\n")
	length = 256
 pad = []
 for counter in range(256):
	pad.append([])
 for column in range(length):
	tmp = shuffle(range(256))
	for row in range(256):
 	pad[row].append(tmp[row])
 stderr.write("Pad generated, %d layers.\n" % (length))
 return pad

def encrypt(filename,pad):
 try:
	stderr.write("Encrypting %s with %d-layer pad..." % (filename,len(pad[0])))
	f = open(filename,'rb')
	out = open(filename + '.e','wb')
	padsize = len(pad[0])
	buffer = bytearray(f.read(padsize))
	while buffer != '':
 	for x in range(len(buffer)):
 	c = buffer[x]
 	buffer[x] = pad[c][x]
 	out.write(buffer)
 	buffer = bytearray(f.read(padsize))
	f.close()
	out.close()
	stderr.write("Encryption complete.\n")
	return 0
 except:
	stderr.write("Could not encrypt file.\n")
	try:
 	unlink(filename + '.e')
	except:
 	pass
	return -1

def encpipe(pad):
 try:
	padsize = len(pad[0])
	buffer = bytearray(stdin.read(padsize))
	while buffer != '':
 	for x in range(len(buffer)):
 	c = buffer[x]
 	buffer[x] = pad[c][x]
 	stdout.write(str(buffer))
 	buffer = bytearray(stdin.read(padsize))
	stderr.write("Encryption complete.\n")
	return 0
 except:
	stderr.write("Encryption failed.\n")
	return -1

def decrypt(filename,pad):
 try:
	stderr.write("Decrypting %s with %d-layer pad..." % (filename,len(pad[0])))
	f = open(filename,'rb')
	out = open(filename[:len(filename)-2],'wb')
	padsize = len(pad[0])
	buffer = bytearray(f.read(padsize))
	while buffer != '':
 	for x in range(len(buffer)):
 	c = buffer[x]
 	k = 0
 	while pad[k][x] != c:
 	k += 1
 	if k >= 256:
 	stderr.write("Key not found in pad... range exceeded.\n")
 	try:
 	unlink(filename[:len(filename)-2])
 	except:
 	pass
 	return -1
 	buffer[x] = k
 	out.write(buffer)
 	buffer = bytearray(f.read(padsize))
	f.close()
	out.close()
	stderr.write("Decryption complete.\n")
	return 0
 except:
	stderr.write("Could not decrypt file.\n")
	try:
 	unlink(filename[:len(filename)-2])
	except:
 	pass
	return -1

def decpipe(pad):
 try:
	padsize = len(pad[0])
	buffer = bytearray(stdin.read(padsize))
	while buffer != '':
 	for x in range(len(buffer)):
 	c = buffer[x]
 	k = 0
 	while pad[k][x] != c:
 	k += 1
 	if k >= 256:
 	stderr.write("Key not found in pad... range exceeded.\n")
 	return -1
 	buffer[x] = k
 	stdout.write(str(buffer))
 	buffer = bytearray(stdin.read(padsize))
	stderr.write("Decryption complete.\n")
	return 0
 except:
	stderr.write("Could not decrypt file.\n")
	return -1

if __name__ == "__main__":
 if len(argv) < 2:
	stderr.write(usage)
	exit(0)
 elif argv[1] == '-g':
	try:
 	try:
 	layers = int(argv[2])
 	except:
 	layers = 256
 	savepad(genpad(layers))
	except:
 	stderr.write(usage)
 	exit(0)
 elif argv[1] == '-e':
	try:
 	fn = argv[2] 
 	try:
 	pn = argv[3]
 	pad = loadpad(pn)
 	except:
 	pad = genpad()
 	savepad(pad)
 	encrypt(fn,pad)
	except:
 	stderr.write(usage)
 	exit(0)
 elif argv[1] == '-d':
	try:
 	decrypt(argv[2],loadpad(argv[3]))
	except:
 	stderr.write(usage)
 	exit(0)
 elif argv[1] == '-m':
	try:
 	start = int(time())
 	pads = int(argv[2])
 	try:
 	layers = int(argv[3])
 	except:
 	layers = 256
 	for x in range(pads):
 	savepad(genpad(layers))
 	duration = int(time()) - start
 	stderr.write("%d %d-layer pads generated in %d seconds.\n" % (pads,layers,duration))
	except:
 	stderr.write(usage)
 	exit(0)
 elif argv[1] == '-pe':
	try:
 	try:
 	pad = loadpad(argv[2])
 	except:
 	pad = genpad()
 	savepad(pad)
 	encpipe(pad)
	except:
 	stderr.write(usage)
 	exit(0)
 elif argv[1] == '-pd':
	try:
 	pad = loadpad(argv[2])
 	decpipe(pad)
	except:
 	stderr.write(usage)
 	exit(0)
 else:
	stderr.write(usage)
	exit(0)






Also tagged with one or more of these keywords: networking, encryption, network, python, ssh, hash, md5