How do I encrypt with my own key?
I've searched over the net to do this. How do I encrypt with my own key? In python I prefer
cryptography though. It keeps popping out the error Fernet key must be 32 url-safe base64-encoded bytes and TypeError: a bytes-like object is required, not 'str'. I am trying to create a private variable function. I'm python new-comer.
Here is my uncompleted code. Thank you for your help.
from cryptography.fernet import Fernet
import inspect
import hashlib
import base64 #Fernet key must be 32 url-safe base64-encoded bytes
def encode(key, string):
encoded_chars = []
for i in xrange(len(string)):
key_c = key[i % len(key)]
encoded_c = chr(ord(string[i]) + ord(key_c) % 256)
encoded_chars.append(encoded_c)
encoded_string = "".join(encoded_chars)
return base64.urlsafe_b64encode(encoded_string)
class private:
class sec_storage:
data = dict()
hashed_data = dict()
class var:
def create(var,value):
# creates key based on caller
key = hashlib.sha224(str(inspect.stack()).encode()).hexdigest()
cipher_suite = Fernet(base64.b64encode(key)) #Fernet key must be 32 url-safe base64-encoded bytes
# encrypts using key
encoded_text = cipher_suite.encrypt(value)
# prepares storage
hashed_var = hashlib.sha224("plus".join(list(var.encode(),key[:12])).hexdigest())
hashed_value = hashlib.sha224(value.encode()).hexdigest()[12:30]
private.sec_storage.data[hashed_var] = encoded_text
private.sec_storage.hashed_data[hashed_var] = hashed_value
def read(var):
# creates key based on caller
key = hashlib.sha224(str(inspect.stack()).encode()).hexdigest()
cipher_suite = Fernet(base64.b64encode(key)) #Fernet key must be 32 url-safe base64-encoded bytes
# retrieve var
hashed_varname = hashlib.sha224("plus".join(list(var.encode(),key[:12])).hexdigest())
try:
hashed_var = private.sec_storage.data[hashed_varname]
except NameError:
raise NameError("Requested variable not found")
# decrypts using key
decoded_text = cipher_suite.decrypt(hashed_var)
hashed_value = hashlib.sha224(decoded_text.encode()).hexdigest()[12:30]
# checks if password is correct
if private.sec_storage.hashed_data[hashed_varname] != hashed_value:
raise ValueError("Value not as requested")
return decoded_text
private.var.create("myvar","Hello World!")
print(private.var.read("myvar"))
print(sec_storage.data)
As you can see cipher_suite = Fernet(base64.b64encode(key)) #Fernet key must be 32 url-safe base64-encoded
How do I fix it?
hexdigest()and is thus 56 bytes in size and not 32 bytes as required. a bytes-like object is required, not 'str':b64encode()expects a bytes-like object and not a string. Suggestions: (1) A random byte sequence can easily be created withos.urandom()which returns a bytes-like object. (2) For a url safe string you have to useurlsafe_b64encode(). Remark: Usedigest()instead ofhexdigest()if the hash should be returned as bytes-like object.key = hashlib.sha224(...).hexdigest().encode('utf8')[:32].hexdigestto generate a key of sufficient length doubles the length of the string but hugely drops the entropy per byte. Instead of 2**8 (256) values there are now only 2**4 (16). Since Fernet uses the first 128-bits for the AES key and the second 128 as an HMAC key you've reduced the effective key space from 2**128 to 2**64, which is very, very bad. Coupled with it being the hash of the current stack the resulting key would be extremely dangerous.