1

I am trying to obfuscate a string so that it is not easily read by users. However, the obfuscated string should be in form a string that can be stored in a text file, not in byte form to be stored in binary file. I tried some approaches from Simple way to encode a string according to a password? but was not successful:

def myencode(ori_str, key):
    enc = []
    for i in range(len(ori_str)):
        key_c = key[i % len(key)]
        enc_c = (ord(ori_str[i]) + ord(key_c)) % 256
        enc.append(enc_c)
    return base64.urlsafe_b64encode(bytes(enc))

Output of above fn needs to be stored in a binary file. Changing ..._b64encode(bytes(enc)) to ..._b64encode(enc) does not work.

How can I achieve similar result that can be stored in a text file?


Edit: The corresponding decode fn is as follows:

def mydecode(enc_str, key):
    dec = []
    enc_str = base64.urlsafe_b64decode(enc_str)
    for i in range(len(enc_str)):
        key_c = key[i % len(key)]
        dec_c = chr((256 + enc_str[i] - ord(key_c)) % 256)
        dec.append(dec_c)
    return "".join(dec)
rnso
  • 23,686
  • 25
  • 112
  • 234

1 Answers1

1
def myencode_str(ori_str, key):
    enc = []
    for i in range(len(ori_str)):
        key_c = key[i % len(key)]
        enc_c = (ord(ori_str[i]) + ord(key_c)) % 256
        enc.append(enc_c)
    return (base64.urlsafe_b64encode(bytes(enc))).decode("utf-8") 

or see here for a full example:

from cryptography.fernet import Fernet

class Encrypt(object):
    '''
    see https://cryptography.io/en/latest/fernet/
    '''

    @classmethod
    def encrypt(cls, plain_text):
        '''
        @param enctypted_text: str or bytes
        @return cipher_text: str (.decode() converts the byte string to string)
        '''
        if isinstance(plain_text, str):
            plain_text = plain_text.encode()
        elif not isinstance(plain_text, bytes):
            raise ValueError('Value must be string or bytes')
        cipher_suite = Fernet(config.KEY.encode())
        cipher_text = cipher_suite.encrypt(plain_text).decode()
        return cipher_text

    @classmethod
    def decrypt(cls, enctypted_text):
        '''
        @param enctypted_text: str or bytes
        @return plain_text: str (.decode() converts the byte string to string)
        '''
        if isinstance(enctypted_text, str):
            enctypted_text = enctypted_text.encode()
        elif not isinstance(enctypted_text, bytes):
            raise ValueError('Value must be string or bytes')
        cipher_suite = Fernet(config.KEY.encode())
        plain_text = cipher_suite.decrypt(enctypted_text).decode()
        return plain_text

    @classmethod
    def generateKey(cls):
        key = Fernet.generate_key()
        return key*
proximacentauri
  • 1,749
  • 5
  • 25
  • 53
  • Will the decode fn also needs to be altered? I have added the decode fn in the edit to my question above. – rnso Dec 03 '17 at 06:03
  • Not 100% sure on what trying to do but can just encode the string as bytes ie: bytes_out = some_string.encode('utf-8') – proximacentauri Dec 03 '17 at 06:22
  • Can this `bytes_out` be saved as a string in text (not binary) file and read again from it as a string? – rnso Dec 03 '17 at 08:06
  • I could even do with something like this: http://www.rebol.com/docs/words/wenbase.html , although there is no password key in this. – rnso Dec 03 '17 at 08:07
  • see https://cryptography.io/en/latest/fernet/ for a good easily useable encrypt/decrypt sequence – proximacentauri Dec 03 '17 at 08:20
  • Does it not produce bytes which can only be stored in binary files. I want to store encrypted version as a string in text files. – rnso Dec 03 '17 at 08:32
  • On python2 `dec_c = chr((256 + enc_str[i] - ord(key_c)) % 256)` gives error: `TypeError: unsupported operand type(s) for +: 'int' and 'str'`. How can I solve this? – rnso Dec 05 '17 at 17:19