I have generated few fernet keys and stored in str format for reference.
Now, I need to encode these fernet keys in str format to 32 url-safe base64-encoded bytes to decrypt my data.
from cryptography.fernet import Fernet as frt
keys=set()
keybin='keys'
keybin=open(keybin,'w')
for i in range(r.randint(5,14)):
key=frt.generate_key()
keys.add(key.decode())
for k in keys:
keybin.write(str(k))
keybin.write('\n')
I'm using below code to access the file and decrypt s
key=linecache.getline(cfile,x).encode()
key=base64.b64encode(key)
print(key)
f=frt(key)
token =f.decrypt(s.encode())
But is giving me the below error:
"Fernet key must be 32 url-safe base64-encoded bytes."
ValueError: Fernet key must be 32 url-safe base64-encoded bytes.
Try your code without base64 encoding your key ie:
from cryptography.fernet import Fernet as frt
key=frt.generate_key()
s = "message"
print('input string: {0}'.format(s))
#key=base64.b64encode(key) #no need to do this
print('key: {0}, type: {1}'.format(key, type(key)))
f=frt(key)
token = f.encrypt(s.encode('utf-8')) #need to convert the string to bytes
print ('encrypted: {0}'.format(token))
output = f.decrypt(token)
output_decoded = output.decode('utf-8')
print ('decrypted: {0}'.format(output_decoded))
Related
so i want to encrypt text to audio mp3. but when i run the code, there's error message Exception Type: AssertionError. and it's say there's error at
assert len(key) == key_bytes
can someone please check what's error with the function? i want encrypt using AES 128 and 256, please help me.
from Crypto.Cipher import AES
from Crypto.Util import Counter
from Crypto import Random
import binascii
key_bytes = 16
# Takes as input a 32-byte key and an arbitrary-length plaintext and returns a
# pair (iv, ciphtertext). "iv" stands for initialization vector.
def encrypt(key, testaudio):
assert len(key) == key_bytes
print(testaudio)
print(key)
# Choose a random, 16-byte IV.
iv = Random.new().read(AES.block_size)
# Convert the IV to a Python integer.
iv_int = int(binascii.hexlify(iv), 16)
# Create a new Counter object with IV = iv_int.
ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)
# Create AES-CTR cipher.
aes = AES.new(key, AES.MODE_CTR, counter=ctr)
# Encrypt and return IV and ciphertext.
ciphertext = aes.encrypt(testaudio)
print(iv)
print(ciphertext)
return (iv, ciphertext)
at my view, i call the function like this. where testaudio have file audio mp3.
enkripsi = encrypt("testing", testaudio)
print(enkripsi)
You have defined the value of key_bytes as 16 but in your encrypt function you are using assert to check whether the length of key which is 7 when you are calling the function(length of word "testing"), either you change the value of key_bytes or change the value of key which you are passing when calling your function.
Edited:
import random, string
len_16_string = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
print(len_16_string)
enkripsi = encrypt(len_16_string, testaudio)
print(enkripsi)
I want to decode a string and decrypte it by a private key with RSA algorithm. First of all, I try to decode a string by base64. but when I use base64.b64decode(),I've got an error about Incorrect Padding. (key variable is my string which is cyphertext to decrypt by RSA)
key = contract['key']
b64_dec_key = base64.b64decode(key)
sym_key = self.decrypt_with_private_key(b64_dec_key)
when I want to fix this bug, I add '===' to key and use base64.urlsafe_b64decode instead of base64.b64decode() as follows:
key = contract['key']
b64_dec_key = base64.urlsafe_b64decode(key + '===')
sym_key = self.decrypt_with_private_key(b64_dec_key)
and the string which I want to decrypt is as follows:
-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnhvO8SVZi7LuDElGkNcq\nU5kSOG69NiCj0RPQaOQySeUsdBLTZ5vWSH6WtIhrJyxpzrulEDDfW72v1GuCo7jt\nxc1oDDW9GQPPYicp7sh03j/lzf17Wbffx7cRVl5gRxJl4myEWnk/i+WDSugLFwsx\nZX+G38UbfFPbvqpWO2MYgEjOLLkXjB/oGzp/qvUbwlauUQ16wgd1L+lZAv7r4C2w\ni3ATMK1w0HtTmoaV+lT17Fh+9IONuz56mFT7SZH6FCdkn7nGKAormJCXDpaJ60E1\nM8LKHBIc4G68e1JmSvLGzy2Y3Da6Q3FfPZQuzTbigSAdbt1i4/GI/Ot/YsorvqRL\n7wIDAQAB\n-----END
PUBLIC KEY-----\n
but I got another error about key size.
ValueError: Ciphertext length must be equal to key size.
For decrypting the ciphertext (I mean key) I use the following code:
def decrypt_with_private_key(self, cipher_message):
private_key_pem = self.decrypt_private_key_file()
private_key_load = serialization.load_pem_private_key(
private_key_pem.encode(),
password=None,
backend=default_backend()
)
plain_message = private_key_load.decrypt(
cipher_message,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return plain_message.decode('UTF-8')
how can I fix these errors?
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?
The primary issue here is that Fernet expects a url-safe base64 encoded string that decodes to 32 bytes. The security of this construction relies on those 32 bytes containing sufficient entropy such that an attacker can't feasibly guess it.
In your example you're using the SHA224 hash of a stack trace. There are a few issues at play:
224 bits/8 bits per byte=28 bytes, which is not a sufficiently long output.
Hashing a stack trace is not a safe method of deriving a key.
You've encoded via vanilla base64 when it should use urlsafe_b64encode.
In general it's best to generate your Fernet key with Fernet.generate_key(), but that requires you to store the key somewhere for later use. If you want to generate a key from something like a password the documentation has an example (https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet).
from docx import Document
from Crypto.Cipher import AES
document = Document('test.docx')
allText = ""
for docpara in document.paragraphs:
allText+=(docpara.text)
key="1234567891011121"
cipher=AES.new(key,AES.MODE_ECB)
msg=cipher.encrypt(allText)
I want to encrypt a Docx file in python.But when i run this code:
raise TypeError("Object type %s cannot be passed to C code" % type(data))
TypeError: Object type cannot be passed to C code
How can i solve this problem?
From the documentation:
>>> from Crypto.Cipher import AES
>>> from Crypto import Random
>>>
>>> key = b'Sixteen byte key'
>>> iv = Random.new().read(AES.block_size)
>>> cipher = AES.new(key, AES.MODE_CFB, iv)
>>> msg = iv + cipher.encrypt(b'Attack at dawn')
I think your key needs to be converted to bytes first, and the object to be encrypted too. Notice the b' before both.
You also need to add an initialization vector (iv) to use for the encryption.
I am trying to decrypt an AES encrypted data.
I am having the key and iv with me but I think key is also encoded.
Here is the code I have used:
import binascii
from Crypto.Cipher import AES
enckey = '5f35604280b44dd1073f7ee83e346d81'
key = binascii.unhexlify(enckey)
key32 = "{: <32}".format(key).encode("utf-8")
data='692fa1deafad8ad80b98cd6f077899e9be457ac5364c3822aae9457d4912e4829d71cb
8702bd10e1d54f7a0461edba193517b353835480bd174804f586776e623473022548ff098a95
45b608282bf498a36968dd6b858ad631f6eaa79ea1a87c984f4a8da5a9d1cee1b11b32d46c0d
2a670d4e634ecc47c7105387a0a38853c91e10747170de69ebf6f0e1a99f0134ddb0af0cec2c
fc70f53c9eab7227460cf1153ef686a5dc5014bd286fb0efdec571327f5a4874bec5fd5c65f0
9f0ed10e906e4199dd8c3cb8340aca1904f486a70b02554581f0e723d22854188e933ed9fce6
0172099bc675b89eba39651bbc0658ae264213217f14ff4f0824494585d8856dfd44e4ce9505
e43762a9f1ea48f9c736603e83c3e10c5740cdf279dc3a914e19eee089160ffa91180d1b4299
38ab1b6a4272d1779f7702f760cbac3f35fc35c16fcf21c7e00183f306e7a18f71ffb3b62b91
250dca7dd627876a6cedbfe83f0f18abbbb7c7650566a7f761844243fe1271cef22b1026a3f1
d37b8e7bd7c068331897680ec101e269ce66c3f129de33d3277c2cc120feb88f77f1bb851d41
b83468128366b7ed92ae07f37675cee07355ebcdfcba90a690e3d4817cd18123a0c9de175ea6
c5049c51170ee73facd5148f6525024116991b0601598a3501e770493dab0653e146981e91d2
ea9c50fbd1e6b8bb38407655c518f30852ce43ed62d1c578e642c4fa92f00bbf102c3418ed52
ed23138c86d327bbc4718ec44440f289e3af6c096c7ad69af5d941768b0f4b2e3decfad5dcfe
6dc491ce4f2f9d86d226b87f19dfb56dc44f6d66820773e6fcfa4fcd7958da2d639037627057
99a414baf93081242c2b594981c93b892f4f28883203875a4010ace9a5eafea51ee406'
cipher_text = binascii.unhexlify(data)
# Decryption
decryption_suite = AES.new('key32', AES.MODE_CBC, 'heF9BATUfWuISyO8')
plain_text = decryption_suite.decrypt(cipher_text)
print plain_text
And this is the error I am receiving :
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 4:
ordinal not in range(128)
I am unable to figure out the problem with my key and data...
And please let me know if I have to make any changes to my code.
The following code works:
from Crypto.Cipher import AES
keyAscii = '5f35604280b44dd1073f7ee83e346d81'
keyBinary = bytes(keyAscii, 'ascii')
ciphertextHex='692fa1deafad8ad80b98cd6f077899e9be457ac5364c3822aae9457d4912e4829d71cb8702bd10e1d54f7a0461edba193517b353835480bd174804f586776e623473022548ff098a9545b608282bf498a36968dd6b858ad631f6eaa79ea1a87c984f4a8da5a9d1cee1b11b32d46c0d2a670d4e634ecc47c7105387a0a38853c91e10747170de69ebf6f0e1a99f0134ddb0af0cec2cfc70f53c9eab7227460cf1153ef686a5dc5014bd286fb0efdec571327f5a4874bec5fd5c65f09f0ed10e906e4199dd8c3cb8340aca1904f486a70b02554581f0e723d22854188e933ed9fce60172099bc675b89eba39651bbc0658ae264213217f14ff4f0824494585d8856dfd44e4ce9505e43762a9f1ea48f9c736603e83c3e10c5740cdf279dc3a914e19eee089160ffa91180d1b429938ab1b6a4272d1779f7702f760cbac3f35fc35c16fcf21c7e00183f306e7a18f71ffb3b62b91250dca7dd627876a6cedbfe83f0f18abbbb7c7650566a7f761844243fe1271cef22b1026a3f1d37b8e7bd7c068331897680ec101e269ce66c3f129de33d3277c2cc120feb88f77f1bb851d41b83468128366b7ed92ae07f37675cee07355ebcdfcba90a690e3d4817cd18123a0c9de175ea6c5049c51170ee73facd5148f6525024116991b0601598a3501e770493dab0653e146981e91d2ea9c50fbd1e6b8bb38407655c518f30852ce43ed62d1c578e642c4fa92f00bbf102c3418ed52ed23138c86d327bbc4718ec44440f289e3af6c096c7ad69af5d941768b0f4b2e3decfad5dcfe6dc491ce4f2f9d86d226b87f19dfb56dc44f6d66820773e6fcfa4fcd7958da2d63903762705799a414baf93081242c2b594981c93b892f4f28883203875a4010ace9a5eafea51ee406'
ciphertextBinary = bytes.fromhex(ciphertextHex)
ivAscii = 'heF9BATUfWuISyO8'
ivBinary = bytes(ivAscii, 'ascii')
# Decryption
decrypter = AES.new(keyBinary, AES.MODE_CBC, ivBinary)
plaintextBinary = decrypter.decrypt(ciphertextBinary)
plaintext = plaintextBinary.decode('utf-8')
print(plaintext)
and outputs
connection_type=wifi&android_id=863e87fea9a09533&app_name=AstroNest&app_version=53&app_version_name=2.7.1&device_brand=motorola&device_cpu_type=armv7l&device_model=XT1562&google_aid=ab95a01a-242b-4ac2-ad12-b6189e983a56&google_ad_tracking_disabled=0&insdate=1494826343&installer=com.android.vending&language=en&mac_address=02%3A00%3A00%3A00%3A00%3A00&mat_id=45c0a743-a948-434b-a20d-fe66e870d285&os_version=6.0.1&screen_density=3.0&screen_layout_size=1920x1080&sdk_version=3.11.4&conversion_user_agent=Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+6.0.1%3B+XT1562+Build%2FMPDS24.107-70-1-5%29¤cy_code=USD&revenue=0.0&system_date=1494826532
But it's cryptographically wrong in many ways:
The key looks like 32 character hex string (which would encode a 128-bit key), but you actually need to treat it as ASCII encoding a 32-byte key. That's wrong, since keys are supposed to be uniformly distributed binary string
Similarly an IV is supposed to be a uniform binary, but it's actually ASCII
The IV is fixed, but the whole point of an IV is to be different (unpredictably random for CBC mode) for each message.
CBC mode is vulnerable to padding oracle attacks, which allow an active attacker to recover the plaintext if they can execute a chosen ciphertext attack where they learn which ciphertext decrypt successfully.
You should use authenticated encryption with unique IVs instead.
this one may help you
import binascii
from Crypto.Cipher import AES
import re
enckey = '5f35604280b44dd1073f7ee83e346d81'
key32 = "{: <32}".format(enckey).encode("utf-8")
cipher = AES.new(key32, AES.MODE_ECB)
data='692fa1deafad8ad80b98cd6f077899e9be457ac5364c3822aae9457d4912e4829d71cb8702bd10e1d54f7a0461edba193517b353835480bd174804f586776e623473022548ff098a9545b608282bf498a36968dd6b858ad631f6eaa79ea1a87c984f4a8da5a9d1cee1b11b32d46c0d2a670d4e634ecc47c7105387a0a38853c91e10747170de69ebf6f0e1a99f0134ddb0af0cec2cfc70f53c9eab7227460cf1153ef686a5dc5014bd286fb0efdec571327f5a4874bec5fd5c65f09f0ed10e906e4199dd8c3cb8340aca1904f486a70b02554581f0e723d22854188e933ed9fce60172099bc675b89eba39651bbc0658ae264213217f14ff4f0824494585d8856dfd44e4ce9505e43762a9f1ea48f9c736603e83c3e10c5740cdf279dc3a914e19eee089160ffa91180d1b429938ab1b6a4272d1779f7702f760cbac3f35fc35c16fcf21c7e00183f306e7a18f71ffb3b62b91250dca7dd627876a6cedbfe83f0f18abbbb7c7650566a7f761844243fe1271cef22b1026a3f1d37b8e7bd7c068331897680ec101e269ce66c3f129de33d3277c2cc120feb88f77f1bb851d41b83468128366b7ed92ae07f37675cee07355ebcdfcba90a690e3d4817cd18123a0c9de175ea6c5049c51170ee73facd5148f6525024116991b0601598a3501e770493dab0653e146981e91d2ea9c50fbd1e6b8bb38407655c518f30852ce43ed62d1c578e642c4fa92f00bbf102c3418ed52ed23138c86d327bbc4718ec44440f289e3af6c096c7ad69af5d941768b0f4b2e3decfad5dcfe6dc491ce4f2f9d86d226b87f19dfb56dc44f6d66820773e6fcfa4fcd7958da2d63903762705799a414baf93081242c2b594981c93b892f4f28883203875a4010ace9a5eafea51ee406'
cipher_text = binascii.unhexlify(data)
# Decryption
plain_text = re.sub('\0*$','', cipher.decrypt( data[16:]))
print plain_text
or try this
import binascii
from Crypto.Cipher import AES
enckey = '5f35604280b44dd1073f7ee83e346d81'
key32 = "{: <32}".format(enckey).encode("utf-8")
cipher = AES.new(key32, AES.MODE_ECB)
data='692fa1deafad8ad80b98cd6f077899e9be457ac5364c3822aae9457d4912e4829d71cb8702bd10e1d54f7a0461edba193517b353835480bd174804f586776e623473022548ff098a9545b608282bf498a36968dd6b858ad631f6eaa79ea1a87c984f4a8da5a9d1cee1b11b32d46c0d2a670d4e634ecc47c7105387a0a38853c91e10747170de69ebf6f0e1a99f0134ddb0af0cec2cfc70f53c9eab7227460cf1153ef686a5dc5014bd286fb0efdec571327f5a4874bec5fd5c65f09f0ed10e906e4199dd8c3cb8340aca1904f486a70b02554581f0e723d22854188e933ed9fce60172099bc675b89eba39651bbc0658ae264213217f14ff4f0824494585d8856dfd44e4ce9505e43762a9f1ea48f9c736603e83c3e10c5740cdf279dc3a914e19eee089160ffa91180d1b429938ab1b6a4272d1779f7702f760cbac3f35fc35c16fcf21c7e00183f306e7a18f71ffb3b62b91250dca7dd627876a6cedbfe83f0f18abbbb7c7650566a7f761844243fe1271cef22b1026a3f1d37b8e7bd7c068331897680ec101e269ce66c3f129de33d3277c2cc120feb88f77f1bb851d41b83468128366b7ed92ae07f37675cee07355ebcdfcba90a690e3d4817cd18123a0c9de175ea6c5049c51170ee73facd5148f6525024116991b0601598a3501e770493dab0653e146981e91d2ea9c50fbd1e6b8bb38407655c518f30852ce43ed62d1c578e642c4fa92f00bbf102c3418ed52ed23138c86d327bbc4718ec44440f289e3af6c096c7ad69af5d941768b0f4b2e3decfad5dcfe6dc491ce4f2f9d86d226b87f19dfb56dc44f6d66820773e6fcfa4fcd7958da2d63903762705799a414baf93081242c2b594981c93b892f4f28883203875a4010ace9a5eafea51ee406'
cipher_text = binascii.unhexlify(data)
# Decryption
plain_text = cipher.decrypt(cipher_text)
print plain_text