4 Replies - 955 Views - Last Post: 04 March 2015 - 09:50 PM Rate Topic: -----

#1 Hrand   User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 109
  • Joined: 25-June 12

One time Pad Encryption Code --> Thoughts on what I have so far?

Posted 23 February 2015 - 09:37 PM

#!/usr/bin/env python2.7
from random import choice
import pyminizip
import os
import zipfile
import datetime


class OneTimePadEncryption:
    """This Class was designed to apply a one time pad encryption
    on textual data that either comes from a file or that is entered
    manually by the user. NOTE** the program can only handle the
    standard english alphabet and basic punctuation.  Note, they suffix
    of the key file and the suffix of the encrypted message file will be the
    same.  This allows users to associate key files with their corresponding
    encrypted text files"""
    def __init__(self):
        self.my_key = None
        self.my_string = None
        self.string_list = None
        self.key_list = None
        self.file_data = None
        self.timestamp = None

    __alpha_dictionary = {
        0: ["a"],
        1: ["b"],
        2: ["c"],
        3: ["d"],
        4: ["e"],
        5: ["f"],
        6: ["g"],
        7: ["h"],
        8: ["i"],
        9: ["j"],
        10: ["k"],
        11: ["l"],
        12: ["m"],
        13: ["n"],
        14: ["o"],
        15: ["p"],
        16: ["q"],
        17: ["r"],
        18: ["s"],
        19: ["t"],
        20: ["u"],
        21: ["v"],
        22: ["w"],
        23: ["x"],
        24: ["y"],
        25: ["z"],
        26: [" "],
        27: ["."],
        28: [","],
        29: ["?"],
        30: ["!"],
        31: ['"'],
        32: [";"]

    }

    def __string_converter(self, e_d_string_or_key_string):
        """Takes a given string or file, whether it is the encrypted string,
         plaintext(or decrypted string), or the generated key string and
         and translates it based on the provided alpha dictionary.
         NOTE** all strings are converted to lowercase."""
        plaintext = str(e_d_string_or_key_string).lower()
        string_list = []
        for ch in plaintext:
            for k, v in self.__alpha_dictionary.items():
                if ch in v:
                    string_list.append(k)
                else:
                    continue

        return string_list

    def __key_generator(self, standard_string_length):
        """Generates a random list of letters that is equal to
        the length of the provided string.  The list is based on on the
        key_values variable below, which is
        a list if ascii values"""
        filename = "_".join(["key", self.timestamp])
        string_length = len(standard_string_length)
        key_list = []
        key_values = [32, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
                      113, 114, 115, 116, 117, 118, 119, 120, 121, 122]

        for i in xrange(string_length):
            key_list.append(chr(choice(key_values)))
        with open(filename + ".dat", 'w') as data:
            temp_string = ""
            for key in key_list:
                temp_string += key
            data.write(temp_string)
        return self.__string_converter("".join(key_list))

    def __encrypt_file(self, zip_password):
        """Encrypts the key.dat file with a zip encryption using pyminizip.
        For more instructions regarding pyminizip you visit pypi.python.org
        and search for the module."""
        filename = "_".join(["key", self.timestamp])
        pyminizip.compress(filename + ".dat", filename + ".zip", zip_password, int(9))
        os.remove(filename + ".dat")

    def decrypt_file(self, zip_password):
        """Unzips key.zip file using a supplied password"""
        zipfile.ZipFile("key.zip").extractall(pwd=zip_password)

    def decrypt_string_or_file(self, key, encrypted_string, key_file_mode=False, encrypted_string_file_mode=False):
        """Method that takes either the key or the encrypted string as a
        string or can the key and encrypted string a as file and decrypts
        the string using the provided string. NOTE** In order to use the the key.dat file
        you must first also be able to unzip it using a password."""
        if key_file_mode is True:
            self.my_key = key
            with open(self.my_key, 'r') as key_data:
                self.my_key = key_data.read()
        else:
            self.my_key = key
        if encrypted_string_file_mode is True:
            self.my_string = encrypted_string
            with open(self.my_string, 'r') as string_data:
                self.my_string = string_data.read()
        else:
            self.my_string = encrypted_string

        my_string_num_list = self.__string_converter(self.my_string)
        my_key_num_list = self.__string_converter(self.my_key)

        combined_list_values = []
        for j in xrange(len(my_string_num_list)):
            combined_list_values.append(my_string_num_list[j] - my_key_num_list[j])

        decrypted_list = [k % 33 for k in combined_list_values]

        message = []
        for num in decrypted_list:
            for k, v in self.__alpha_dictionary.items():
                if k == num:
                    message.append(str(v))
        decrypted_string = "".join(message).replace("[", "").replace("]", "").replace("'", "")
        with open("decrypted_message.txt", 'w') as message:
            message.write(decrypted_string)
        return decrypted_string

    def encrypt_string_or_file(self, plain_text, string_file_mode=False):
        """Method that takes either the key or plaintext as a
        string or file. The key is randomly generated for you!"""
        self.timestamp = str(datetime.datetime.now().strftime("%y%m%d_%H%M%S"))
        filename = "_".join(["encrypted_message", self.timestamp])

        if string_file_mode is True:
            with open(plain_text) as plaintext_data:
                self.file_data = str(plaintext_data.read())
                self.string_list = self.__string_converter(self.file_data)
                self.key_list = self.__key_generator(self.file_data)
        else:
            self.string_list = self.__string_converter(plain_text)
            self.key_list = self.__key_generator(plain_text)

        combined_list_values = []

        for j in xrange(len(self.string_list)):
            combined_list_values.append(self.string_list[j] + self.key_list[j])

        encrypted_list = [k % 33 for k in combined_list_values]

        message = []
        for num in encrypted_list:
            for k, v in self.__alpha_dictionary.items():
                if k == num:
                    message.append(str(v))
        encrypted_string = "".join(message).replace("[", "").replace("]", "").replace("'", "")
        with open(filename + ".txt", 'w') as message:
            message.write(encrypted_string)

        self.__encrypt_file(raw_input("Please type in a password to zip and encrypt the key.dat file\n"))

        return encrypted_string



example or how to use code

#!/usr/bin/env python2.7
from OneTimePadEncryption import *

otpe = OneTimePadEncryption()
otpe.encrypt_string_or_file("Hello World. Are you ready for this awesome test?")
#otpe.decrypt_file("helloworld")
#print otpe.decrypt_string_or_file("key.dat", "encrypted_message.txt", key_file_mode=True, encrypted_string_file_mode=True)



Is This A Good Question/Topic? 0
  • +

Replies To: One time Pad Encryption Code --> Thoughts on what I have so far?

#2 Hrand   User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 109
  • Joined: 25-June 12

Re: One time Pad Encryption Code --> Thoughts on what I have so far?

Posted 26 February 2015 - 06:29 PM

just incase anyone is interested in trying out the script.

https://github.com/m...-Pad-Encryption

I'm slowly adding functionality to it.
Was This Post Helpful? 0
  • +
  • -

#3 jon.kiparsky   User is offline

  • Beginner
  • member icon


Reputation: 12350
  • View blog
  • Posts: 20,984
  • Joined: 19-March 11

Re: One time Pad Encryption Code --> Thoughts on what I have so far?

Posted 26 February 2015 - 09:48 PM

So, one thing I'd suggest is that you treat encryption as working on a stream of bytes, and not worry too much about the content of those bytes. Typical one-time pad implementation uses a random (or pseudo-random) stream of bytes and xors against those. You savvy xor? C XOR 6 = 0001 0100 XOR 0000 0110 = 0001 0010 = ten. Doesn't matter whether the bytes represent letters or pixels or what. See Dan Boneh's cryptography course on coursera for some good learning about contemporary crypto.
Was This Post Helpful? 1
  • +
  • -

#4 Hrand   User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 109
  • Joined: 25-June 12

Re: One time Pad Encryption Code --> Thoughts on what I have so far?

Posted 26 February 2015 - 10:04 PM

Awesome, I will certainly take a look into that. I was just tinkering around one day and I came across one time pad encryption, so i decided to implement my own version for fun.
Was This Post Helpful? 0
  • +
  • -

#5 Hrand   User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 109
  • Joined: 25-June 12

Re: One time Pad Encryption Code --> Thoughts on what I have so far?

Posted 04 March 2015 - 09:50 PM

View Postjon.kiparsky, on 26 February 2015 - 09:48 PM, said:

So, one thing I'd suggest is that you treat encryption as working on a stream of bytes, and not worry too much about the content of those bytes. Typical one-time pad implementation uses a random (or pseudo-random) stream of bytes and xors against those. You savvy xor? C XOR 6 = 0001 0100 XOR 0000 0110 = 0001 0010 = ten. Doesn't matter whether the bytes represent letters or pixels or what. See Dan Boneh's cryptography course on coursera for some good learning about contemporary crypto.


I took your advice and rewrote the code

#!/usr/bin/env python2.7
__author__ = 'marcsantiago'
from random import choice
from binascii import hexlify, unhexlify
from sys import exit, stdout
from pyminizip import compress
from os import remove
from zipfile import ZipFile
from datetime import datetime

class OneTimePadEncryption:
    """This Class was designed to apply a one time pad encryption
    on textual data that either comes from a file or that is entered
    manually by the user.  Note, the suffix of the key file and the suffix
    of the encrypted message file will be the same.  This allows
    users to associate key files with their corresponding
    encrypted text files"""
    def __init__(self):
        self.my_key = None
        self.my_string = None
        self.string_list = None
        self.key_list = None
        self.file_data = None
        self.timestamp = None

    def __string_converter(self, text_data):
        """Takes a given string or file and converts it to binary"""
        return bin(int(hexlify(text_data), 16))

    def __key_generator(self, standard_string_length):
        """Generates a random list that is equal to
        the length of the provided string."""
        print "Generating Key Please Wait..."
        filename = "_".join(["key", self.timestamp])
        string_length = len(standard_string_length)
        key_list = []
        key_values = range(65, 123)
        for i in xrange(string_length):
            key_list.append(chr(choice(key_values)))

        with open(filename + ".dat", 'w') as data:
            temp_string = ""
            for key in key_list:
                temp_string += key
            data.write(temp_string)
        return self.__string_converter("".join(key_list))
    
    def __password_checker(self, zip_password):
        """checks the password the user entered to zip secure the key.dat file.
        Warns the user if the password is too weak and prompts the user if they
        wish to continue if the password is too weak."""
        cap = 0
        special = 0
        num = 0
        if len(zip_password) < 8:
            print "Warning! The password you have entered is less then 8 character."
            answer = raw_input("do you wish to continue? [y] or [n]\n").lower()
            if answer not in ['y', 'yes']:
                print "Exiting Program..."
                exit(0)
        for ch in zip_password:
            if ch.isdigit():
                num += 1
            elif ch.isupper():
                cap += 1
            elif ch in "!@#$%^&*":
                special += 1
        if num == 0 or cap == 0 or special == 0:
            print "The password you have entered is weak."
            print "A strong password should contain at least one number, one uppercase, and one special character."
            print "Your password contains %d numbers, %d uppercase letters, and %d special characters"\
                  % (num, cap, special)
            answer = raw_input("do you wish to continue? [y] or [n]\n").lower()
            if answer not in ['y', 'yes']:
                print "Exiting Program..."
                exit(0)
            else:
                answer = raw_input("Do you wish to write your zip password to file? [y] or [n]\n").lower()
                if answer in ['y', 'yes']:
                    with open("zip_password.txt", 'w') as data:
                        data.write(zip_password)
                        return zip_password
                else:
                    return zip_password
        else:
            return zip_password
                    
    def __encrypt_file(self, zip_password):
        """Encrypts the key.dat file with a zip encryption using pyminizip.
        For more instructions regarding pyminizip you visit pypi.python.org
        and search for the module."""
        filename = "_".join(["key", self.timestamp])
        compress(filename + ".dat", filename + ".zip", zip_password, int(9))
        remove(filename + ".dat")

    def decrypt_file(self, zip_file, zip_password):
        """Unzips key.zip file using a supplied password"""
        ZipFile(zip_file).extractall(pwd=zip_password)

    def decrypt_string_or_file(self, key, encrypted_string, key_file_mode=False, encrypted_string_file_mode=False):
        """Method that takes either the key or the encrypted string as a
        string or can the key and encrypted string a as file and decrypts
        the string using the provided string. NOTE** In order to use the the key.dat file
        you must first also be able to unzip it using a password."""
        print "Starting Decryption..."
        if key_file_mode is True:
            self.my_key = key
            with open(self.my_key, 'r') as key_data:
                self.my_key = key_data.read()
        else:
            self.my_key = key
        if encrypted_string_file_mode is True:
            self.my_string = encrypted_string
            with open(self.my_string, 'r') as string_data:
                self.my_string = string_data.read()
        else:
            self.my_string = encrypted_string

        my_string_num_list = self.my_string
        my_key_num_list = self.__string_converter(self.my_key)

        decrypt_list = []
        count = 2
        bar_length = 20
        for j in xrange(2, len(my_string_num_list)):
            percent = float(count) / len(my_key_num_list)
            hashes = "#" * int(round(percent * bar_length))
            spaces = " " * (bar_length - len(hashes))
            stdout.write("\rPercent: [{0}] {1}%".format(hashes + spaces, int(round(percent * 100))))
            stdout.flush()
            decrypt_list.append(int(my_string_num_list[j]) ^ int(my_key_num_list[j]))
            count += 1
        print
        decrypt_list = [str(i) for i in decrypt_list]
        add_binary = "0b" + "".join(decrypt_list)
        decrypted_string = int(add_binary, 2)
        message = unhexlify('%x' % decrypted_string)

        with open("decrypted_message.txt", 'w') as out_message:
            out_message.write(str(message))
        print "Decryption Complete."
        return message

    def encrypt_string_or_file(self, plain_text, string_file_mode=False):
        """Method that takes either the key or plaintext as a
        string or file. The key is randomly generated for you!"""
        print "Starting Encryption..."
        self.timestamp = str(datetime.now().strftime("%y%m%d_%H%M%S"))
        filename = "_".join(["encrypted_message", self.timestamp])
        if string_file_mode is True:
            with open(plain_text) as plaintext_data:
                self.file_data = str(plaintext_data.read())
                self.string_list = self.__string_converter(self.file_data)
                self.key_list = self.__key_generator(self.file_data)
        else:
            self.string_list = self.__string_converter(plain_text)
            self.key_list = self.__key_generator(plain_text)

        encrypted_list = []
        count = 2
        bar_length = 20
        for j in xrange(2, len(self.string_list)):
            percent = float(count) / len(self.string_list)
            hashes = "#" * int(round(percent * bar_length))
            spaces = " " * (bar_length - len(hashes))
            stdout.write("\rPercent: [{0}] {1}%".format(hashes + spaces, int(round(percent * 100))))
            stdout.flush()
            encrypted_list.append(int(self.string_list[j]) ^ int(self.key_list[j]))
            count += 1
        print
        encrypted_list = [str(i) for i in encrypted_list]
        encrypted_data = "0b" + "".join(encrypted_list)

        with open(filename + ".txt", 'w') as message:
            message.write(encrypted_data)

        self.__encrypt_file(self.__password_checker(raw_input("Please type in a password to zip "
                                                              "and encrypt the key.dat file\n")))
        print "Encryption Complete."
        return encrypted_data

def main():
    otpe = OneTimePadEncryption()
    #otpe.encrypt_string_or_file("some_book.txt", string_file_mode=True)
    #otpe.encrypt_string_or_file("Hello World. Are you ready for this awesome test?")
    print otpe.decrypt_string_or_file("key_150305_143506.dat", "encrypted_message_150305_143506.txt", key_file_mode=True, encrypted_string_file_mode=True)

if __name__ == '__main__':
    main()


This post has been edited by Hrand: 05 March 2015 - 01:16 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1