Take the 2-minute tour ×
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It's 100% free, no registration required.

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*"-"
share|improve this question
5  
The answer to "Is my custom crypto implementation secure?" is always "probably not". –  Antimony Jun 28 '13 at 5:36

1 Answer 1

up vote 4 down vote accepted

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!

share|improve this answer
    
I was also wondering about the random number generator, the documentation said that; os.urandom(n) Return a string of n random bytes suitable for cryptographic use. –  kyle k Jun 28 '13 at 4:09
2  
@kylek If "suitable for cryptographic use" is enough then you're missing the point of a one-time pad, which is being provably secure by being completely random. If you use pseudo-random pads you could use a stream cipher instead. Just as secure, but much less inconvenient to use. –  CodesInChaos Jun 28 '13 at 5:52
    
@CodesInChaos While your advice is perfect [+1], let's not forget that (quoting Thomas Pornin) "while One-Time Pad is a stream cipher, stream ciphers are not One-Time Pads." What a mess of definitions… ;) –  e-sushi Oct 22 '13 at 17:23
    
And what @kylek is using is a stream cipher, not a one-time pad. –  Stephen Touset Oct 22 '13 at 17:28

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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