-1
votes
$\begingroup$

This is a program that I made for encrypting text files. It uses a one time pad cipher to encrypt the files, but I do not know if there is any holes in my program that could be a vulnerability. Is my one time pad cipher secure?

import os
q = 1
while q == 1:
    e = raw_input("file to encypt: ")
    #This will open a file for encryption
    o = open(e, "r")
    o1 = o.read()
    #This is the plain text to encrypt
    #'The quick brown fox jumps over the lazy dog'
    plain = o1
    #This will measure the length of the plain text
    f3 = len(plain)
    #generate random chacters as long as the text
    a1 = os.urandom(f3)
    #makes the random characters tuple format
    b = list(a1)
    b2 = list(plain)
    s = plain
    #gives the ascii value of the charters
    L = [ord(c) for c in s]
    s = a1
    a = [ord(c) for c in s]
    b = [ord(c) for c in plain]
    #adds the random digits and the plain text
    c = map(sum, zip(a,b))
    #uses Modular arithmetic if the sum is greater than 256
    x=c
    z = []
    for y in x:
        z.append(y-256 if y>=256 else y)
    z = [y-256 if y >= 256 else y for y in x]
    #converts the sum back to charter form
    cipher_text = ''.join(chr(i) for i in z)
    #makes a folder for the files
    base1 = os.path.basename(e)
    base2 = os.path.splitext(base1)[0]
    #makes a folder for the output
    p = "/Users/kyle/one_time_pad/"+base2
    print p
    if os.path.exists(p):
        print
    else:
        os.mkdir(p)

    key = a1
    #makes a file containg the key
    p = p + "/"
    f2 = p+"key.txt"
    #print f2
    if os.path.exists(f2):
        f1 = file(f2, "w")
        f1 = open(f2, "w")
        f1.write(key)
        f1.close()
    else:
        f1 = file(f2, "w")
        f1 = open(f2, "w")
        f1.write(key)
        f1.close()

    #makes a file containg the cipher text
    f3 = p+"cipher_text.txt"
    if os.path.exists(f3):
        f1 = file(f3, "w")
        f1 = open(f3, "w")
        f1.write(cipher_text)
        f1.close()
    else:
        f1 = file(f3, "w")
        f1 = open(f3, "w")
        f1.write(cipher_text)
        f1.close()

    f4 = p+"encrypt.py"
    encrypt1 = open("/Users/kyle/encrypt.py", "r")
    encrypt = encrypt1.read()
    if os.path.exists(f4):
        f1 = file(f4, "w")
        f1 = open(f4, "w")
        f1.write(encrypt)
        f1.close()
    else:
        f1 = file(f4, "w")
        f1 = open(f4, "w")
        f1.write(encrypt)
        f1.close()

    f5 = p+"decrypt.py"
    encrypt1 = open("/Users/kyle/decrypt.py", "r")
    encrypt = encrypt1.read()
    if os.path.exists(f5):
        f1 = file(f5, "w")
        f1 = open(f5, "w")
        f1.write(encrypt)
        f1.close()
    else:
        f1 = file(f5, "w")
        f1 = open(f5, "w")
        f1.write(encrypt)
        f1.close()

    print 50*"-"

This is the code that i use for decryption

import os

q = 1
while q == 1: 
    #opens the cipher text and it converts it to decimal
    cipher = raw_input("cipher text: ")
    cipher1 = open(cipher, "r")
    cipher2 = cipher1.read()
    cipher3 = [ord(c) for c in cipher2]

    #opens the key and coverts it to decimal
    key = raw_input("key: ")
    key1 = open(key, "r")
    key2 = key1.read()
    key3 = [ord(c) for c in key2]

    #subtracts the key from the cipher
    a = cipher3
    b = key3
    c = map(lambda x: (x[0]-x[1]) % 256, zip(a,b))

    #prints out the decrypted plain text
    decrypt = ''.join(map(chr,c))
    #makes a file with the decrypted output 
    path1 = raw_input("out folder: ")
    name = "plain_text.txt"
    path2 = path1 + "/" + name
    if os.path.exists(path2):
        f1 = file(path2, "a")
        f1 = open(path2, "a")
        f1.write(decrypt)
        f1.close()
    else:
        f1 = file(path2, "w")
        f1 = open(path2, "w")
        f1.write(decrypt)
        f1.close()

    print 50*"-"
$\endgroup$
5
votes
$\begingroup$

The first hole I see is that you're using the random generator urandom. How do you know that the sequence generated by this function is truly random?

The second hole is that you're saving the key as plaintext!

$\endgroup$
-1
votes
$\begingroup$

You should not use os.urandom, as the module is a PRNG based on a seed number. Instead, you should use /dev/random.

Saving the key as plaintext is not a bad idea. It's a HORRIBLE IDEA. If you are coding python on Linux, save the key in a WAVE Audio File. And if you are coding Py' on Windows, save it as Executable Both are a horrible idea of stenography, but it's the basic. And as saving it on these file formats, use DeepSound.
And well, save the key on a hard drive is not recommended. Save it on a USB Flash Drive, Micro SD Card, or, whatever.
Yet make sure the medium containing the key-file it's fully encrypted, i recommend you creating your own AES Hard Drive encryption aplication, or just compiling VeraCrypt from source.
The AES key should be delivered in plaintext, in paper, NOT A DIGITAL MEDIUM, and should be delivered face to face for the message receiver.
When decrypting, the machine shoul'd be FULLY OFFLINE, and far from smartphones, or anything that have a internet connection (WIFI, or Mobile Data), for preventing BitWhisper or Acoustic cryptanalysis.

Sorry if i look like a paranoid, but i am one! ;-)

Source about PRNG, Acoustic cryptanalysis: Wikipedia.
Source about /dev/random: https://cryptoanarchy.freed0m4all.net/wiki/One_Time_Pad

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.