HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Is this a good encryption algorithm?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thisencryptionalgorithmgood

Problem

I've never had a serious attempt at writing an encryption algorithm before, and haven't read much on the subject. I have tried to write an encryption algorithm (of sorts), I would just like to see if anyone thinks it's any good. (Obviously, it's not going to be comparable to those actually used, given that it's a first attempt)

Without further adieu:

def encode(string, giveUserKey = False, doubleEncode = True):
    encoded = [] #Numbers representing encoded characters
    keys = [] #Key numbers to unlonk code
    fakes = [] #Which items in "encoded" are fake
    #All of these are stored in a file

    if giveUserKey:
        userkey = random.randrange(2 ** 10,  2 ** 16)
        # Key given to the user, entered during decryption for confirmation
        # Could change range for greater security
    else:
        userkey = 1

    for char in string:
        ordChar = ord(char)
        key = random.randrange(sys.maxsize)
        encoded.append(hex((ordChar + key) * userkey))
        keys.append(hex(key))

        if random.randrange(fakeRate) == 0:
            fake = hex(random.randrange(sys.maxsize) * userkey)
            encoded.append(fake)
            fakes.append(fake)

    if doubleEncode:
        encoded = [string.encode() for string in encoded]
        keys = [string.encode() for string in keys]
        fakes = [string.encode() for string in fakes]

    hashValue = hex(hash("".join([str(obj) for obj in encoded + keys + fakes]))).encode()

    return encoded, keys, hashValue, fakes, userkey

def decode(encoded, keys, hashValue, fakes, userkey = 1):
    if hash("".join([str(obj) for obj in encoded + keys + fakes])) != eval(hashValue):
        #File has been tampered with, possibly attempted reverse-engineering
        return "ERROR"

    for fake in fakes:
        encoded.remove(fake)

    decoded = ""

    for i in range(len(keys)):
        j = eval(encoded[i]) / userkey
        decoded += chr(int(j - eval(keys[i])))

    return decoded

Solution

Firstly, your encryption is useless. Just run this one line of python code:

print reduce(fractions.gcd, map(eval, encoded))


And it will tell you what your user key is (with a pretty high probability).

Your algorithm is really obfuscation, not encrytion. Encryption is designed so that even if you know the algorithm, but not the key, you can't decryt the message. But your algorithm is basically designed to make it less obvious what the parts mean, not make it hard to decrypt without the key. As demonstrated, retrieving the key is trivial anyways.

def encode(string, giveUserKey = False, doubleEncode = True):


Python convention is lowercase_with_underscores for local names

encoded = [] #Numbers representing encoded characters
    keys = [] #Key numbers to unlonk code
    fakes = [] #Which items in "encoded" are fake
    #All of these are stored in a file

    if giveUserKey:
        userkey = random.randrange(2 ** 10,  2 ** 16)
        # Key given to the user, entered during decryption for confirmation
        # Could change range for greater security


Why isn't the key a parameter?

else:
        userkey = 1

    for char in string:
        ordChar = ord(char)
        key = random.randrange(sys.maxsize)
        encoded.append(hex((ordChar + key) * userkey))
        keys.append(hex(key))


These just aren't keys. Don't call them that.

if random.randrange(fakeRate) == 0:
            fake = hex(random.randrange(sys.maxsize) * userkey)
            encoded.append(fake)
            fakes.append(fake)

    if doubleEncode:
        encoded = [string.encode() for string in encoded]
        keys = [string.encode() for string in keys]
        fakes = [string.encode() for string in fakes]


Since these are all hex strings, why in the world are you encoding them?

hashValue = hex(hash("".join([str(obj) for obj in encoded + keys + fakes]))).encode()

    return encoded, keys, hashValue, fakes, userkey

def decode(encoded, keys, hashValue, fakes, userkey = 1):
    if hash("".join([str(obj) for obj in encoded + keys + fakes])) != eval(hashValue):
        #File has been tampered with, possibly attempted reverse-engineering
        return "ERROR"


Do not report errors by return value, use exceptions.

for fake in fakes:
        encoded.remove(fake)


What if coincidentally one of the fakes looks just like one of the data segments?

decoded = ""

    for i in range(len(keys)):


Use zip to iterate over lists in parallel

j = eval(encoded[i]) / userkey


Using eval is considered a bad idea. It'll execute any python code passed to it and that could be dangerous.

decoded += chr(int(j - eval(keys[i])))


It's better to append strings into a list and join them.

return decoded

Code Snippets

print reduce(fractions.gcd, map(eval, encoded))
def encode(string, giveUserKey = False, doubleEncode = True):
encoded = [] #Numbers representing encoded characters
    keys = [] #Key numbers to unlonk code
    fakes = [] #Which items in "encoded" are fake
    #All of these are stored in a file

    if giveUserKey:
        userkey = random.randrange(2 ** 10,  2 ** 16)
        # Key given to the user, entered during decryption for confirmation
        # Could change range for greater security
else:
        userkey = 1

    for char in string:
        ordChar = ord(char)
        key = random.randrange(sys.maxsize)
        encoded.append(hex((ordChar + key) * userkey))
        keys.append(hex(key))
if random.randrange(fakeRate) == 0:
            fake = hex(random.randrange(sys.maxsize) * userkey)
            encoded.append(fake)
            fakes.append(fake)

    if doubleEncode:
        encoded = [string.encode() for string in encoded]
        keys = [string.encode() for string in keys]
        fakes = [string.encode() for string in fakes]

Context

StackExchange Code Review Q#23492, answer score: 5

Revisions (0)

No revisions yet.