How to hash a variable with sha256 - python-3.x

I have been working on a program that allows you to enter any text you want and it will return the hashed result in sha256. However i am receiving an error on line 4 The whole error message:
Traceback (most recent call last):
File "main.py", line 4, in <module>
hash_object = hashlib.sha256(password_sign_up)
TypeError: Unicode-objects must be encoded before hashing
The code:
import hashlib
password_sign_up = input("Enter your desired password: ")
hash_object = hashlib.sha256(password_sign_up)
hex_dig = hash_object.hexdigest()
print(hex_dig)

You have to use .encode('utf-8') for your password.
In python 2x, the default encoding for any string is unicode. But in 3x, you will have to encode it to your choice of encoding. e.g. utf-32, utf-8 etc.
Try this: hash_object = hashlib.sha256(password_sign_up.encode('utf-8'))

You're taking the result of the input() function (which returns a str object) and putting it directly into sha256(). The sha256() function requires its parameter to be a bytes object.
You can convert a string to a bytes with:
myNewBytesObject = password_sign_up.encode('utf-8')

Related

how can i open a random text file in python?

i am trying to make a python program that randomly selects a text file to open and outputs the contents of the randomly selected text file
when i try running the code, i get this error
Traceback (most recent call last):
File "//fileserva/home$/K59046/Documents/project/project.py", line 8, in
o = open(text, "r")
TypeError: expected str, bytes or os.PathLike object, not tuple
this is the code that i have written
import os
import random
os.chdir('N:\Documents\project\doodoo')
a = os.getcwd()
print("current dir is",a)
file = random.randint(1, 4)
text = (file,".txt")
o = open(text, "r")
print (o.read())
can somebody tell me what i am doing wrong?
As your error message says, your text variable is a tuple, not a string. You can use f-strings or string concatenation to solve this:
# string concatenation
text = str(file) + ".txt"
# f-strings
text = f"{file}.txt"
Your variable text is not what you expect. You currently create a tuple that could look like this: (2, ".txt"). If you want a string like "2.txt", you need to concatenate the two parts:
text = str(file) + ".txt"

Converting list of string to bytes in Python3

I have been trying to convert a list of string elements to bytes so that I can send it to the server.
Below is the snippet for my code:-
ls_queue=list(q.queue)
print("Queue converted to list elements:::",ls_queue)
encoded_list=[x.encode('utf-8') for x in ls_queue]
print("Encoded list:::",encoded_list)
s.send(encoded_list)
The output I get is:
Encoded list::: [b'madhav']
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in
__call__
return self.func(*args)
File "Practice_Client_Server.py", line 149, in Word_Append_Window
s.send(encoded_list)
TypeError: a bytes-like object is required, not 'list'
I can see that it is getting converted to bytes but it still gives the error while trying to encode and send. Can someone take a look as to what I am doing wrong here?
Thank you
You are sending a list object when send is expecting a bytes one, that happened when u converted the elements of the list into bytes but not the list container. What u can do is serialize it as a JSON string and then convert it to bytes, for example:
import json
l = ['foo', 'bar']
l_str = json.dumps(l)
l_bytes = l_str.encode('utf-8')
send(l_bytes)
Then u can read it on your server doing the opposite:
reconstructed_l = json.loads(l_bytes.decode('utf-8'))

Converting md5 hash to a proper 3DES key in python3

I have a function written in c# that you can pass an ascii string as the key, and the encrypted string from a database and decode the data.
I've verified that the code works by writing a simple c# program to decode the data. The code snippet converts the key string to bytes and MD5 hashes it.
C# Code Snippet, omitting some code that converted the byteHash to an ascii string for output in the compiled program
key = "joetest"
byte[] byteHash = cryptoServiceProvider.ComputeHash(Encoding.ASCII.GetBytes(key));
byteHash = "f2fc0f481787cc4cbb15f7ded4412fe4"
I run the following commands and Python3 and get the same byteHash
key = "joetest"
encoded_key = key.encode("ascii")
m = hashlib.md5()
m.update(encoded_key)
hex_key = m.hexdigest()
print(hex_key)
hex_key = "f2fc0f481787cc4cbb15f7ded4412fe4"
I've tried encoding 'hex_key' as binary.
My issue is I'm trying to pass hex_key into 2 different python3 crypto programs. Cryptodome and pyDes. Both tell me that i'm passing in an invalid key.
The C# code that uses byteHash is as follows
tripleDesCryptoServiceProvider.Key = byteHash;
tripleDesCryptoServiceProvider.Mode = CipherMode.ECB;
byte[] byteBuff = Convert.FromBase64String(encryptedString);
string strDecrypted = Encoding.UTF8.GetString(tripleDesCryptoServiceProvider.CreateDecryptor().TransformFinalBlock(byteBuff, 0, byteBuff.Length));
This all works, i was able to decrypt data when i passed in the encrypted string into this function.
Using pyDes i'm using this code
from pyDes import *
import base64
import hashlib
my_data = "fK/jw6/25y0="
#my_data is the word 'test' encrypted with the key of 'joetest'
#This code takes the key string and converts it to an MD5 hash
my_key = "joetest"
encoded_key = my_key.encode("ascii") #Encode the data as binary data
m = hashlib.md5()
m.update(encoded_key)
hex_key = m.hexdigest() #Convert the key to an MD5 hash
encoded_hex_key = hex_key.encode() #Make the MD5 key a binary key
#Convert the Base64 encoded string to the format that the decoder wants
decoded_data = base64.b64decode(my_data)
k = triple_des(encoded_hex_key, ECB, padmode=PAD_PKCS5)
my_out = k.decrypt(decoded_data)
print("my_out")
print(my_out)
exit()
The error i'm getting is:
(3destest) c:\3des-test\3destest>joe3des_test3.py
Traceback (most recent call last):
File "C:\3des-test\3destest\joe3des_test3.py", line 20, in <module>
k = triple_des(encoded_hex_key, ECB, padmode=PAD_PKCS5)
File "c:\3des-test\3destest\lib\site-packages\pyDes.py", line 710, in __init__
self.setKey(key)
File "c:\3des-test\3destest\lib\site-packages\pyDes.py", line 719, in setKey
raise ValueError("Invalid triple DES key size. Key must be either 16 or 24 bytes long")
ValueError: Invalid triple DES key size. Key must be either 16 or 24 bytes long
Using pyCryptodome, i've tried this code
from Cryptodome.Cipher import DES3
import base64
import hashlib
# Converts the key string to an MD5 hash
key = "joetest"
encoded_key = key.encode("ascii")
m = hashlib.md5()
m.update(encoded_key)
hex_key = m.hexdigest()
#Decodes the string to binary digits
encryptedString = base64.b64decode("fK/jw6/25y0=")
#Create the cipher to decrypt the data
cipher = DES3.new(hex_key, DES3.MODE_ECB)
decryptedString = cipher.decrypt(encryptedString)
And i get this error
Traceback (most recent call last):
File "C:\3des-test\3destest\joe3des_test2.py", line 16, in <module>
cipher = DES3.new(hex_key, DES3.MODE_ECB)
File "c:\3des-test\3destest\lib\site-packages\Cryptodome\Cipher\DES3.py", line 174, in new
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
File "c:\3des-test\3destest\lib\site-packages\Cryptodome\Cipher\__init__.py", line 55, in _create_cipher
return modes[mode](factory, **kwargs)
File "c:\3des-test\3destest\lib\site-packages\Cryptodome\Cipher\_mode_ecb.py", line 175, in _create_ecb_cipher
cipher_state = factory._create_base_cipher(kwargs)
File "c:\3des-test\3destest\lib\site-packages\Cryptodome\Cipher\DES3.py", line 99, in _create_base_cipher
key = adjust_key_parity(key_in)
File "c:\3des-test\3destest\lib\site-packages\Cryptodome\Cipher\DES3.py", line 80, in adjust_key_parity
raise ValueError("Not a valid TDES key")
ValueError: Not a valid TDES key
My python MD5 hash is 32 hex characters long. Assuming my math is right, 32 * 4 is 128 bits. And the error is saying it must be 16 or 24 bytes long. 16 * 8 is also 128 bits. So the byte string value i'm passing it should be correct. I think I'm missing something, but can't seem to figure it out.
Update 2-Jan-2018
Based on answer below here's a copy of the code that I used to confirm this will decrypt the data from the DB.
from pyDes import *
import base64
import hashlib
#my_data is the word 'test' encrypted with the key of 'joetest'
my_data = "fK/jw6/25y0="
#This code takes the key string and converts it to an MD5 hash
my_key = "joetest"
encoded_key = my_key.encode("ascii")
m = hashlib.md5()
m.update(encoded_key)
digest_key = m.digest()
#Convert the Base64 encoded string to the format that the decoder wants
decoded_data = base64.b64decode(my_data)
k = triple_des(digest_key, ECB)
my_out = k.decrypt(decoded_data)
print("my_out")
print(my_out.decode("ascii"))
The disconnect here is that pyDes.triple_des() is looking for a binary key, but what you are giving it is an encoded string with the hex representation of that key. Since pyDes doesn't expect the hex string, try just giving it the raw digest instead (i.e. m.digest() instead of m.hexdigest()). No need to .encode() it either.
TripleDES, by definition, is meant to use a 24 byte key, e.g. 192 bits. Implementations that accept less than that actually reuse key data.
In C#, TripleDES with a 128-bit key reuses the first 64 bits to create a key that is 192 bits in length.
With that in mind, try using the following 192-bit key instead:
f2fc0f481787cc4cbb15f7ded4412fe4f2fc0f481787cc4c
If this works, which I expect it will, you'll just need to modify the code to copy the first 64 bits to the end.
The Error
line 80, in adjust_key_parity
raise ValueError("Not a valid TDES key")
Comes from the following code in pyCryptodome:
79 if len(key_in) not in key_size:
80 raise ValueError("Not a valid TDES key")
..
186 # Size of a key (in bytes)
187 key_size = (16, 24)
Your key is 16 bytes long, but in hex form the key you pass have size 32.

Python : Pycrypto RSA public key encryption error

So I've just started experimenting with Pycrypto and wanted to encrypt and decrypt a message, but this code I put together produced some errors.
Here they are:
enc_data = public_key.encrypt
TypeError: unsupported operand type(s) for pow(): 'str', 'int','int'
ciphertext = cipher.encrypt('Bob')
Traceback (most recent call last):
line 22, in
ciphertext = cipher.encrypt('Bob')
File
"C:\Anaconda3\lib\site-packages\Crypto\Cipher\PKCS1_OAEP.py", line 50,
in encrypt
db = lHash + ps + bchr(0x01) + message
TypeError: can't concat bytes to str
The code:
import Crypto
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto import Random
random_generator = Random.new().read
key = RSA.generate(1024, random_generator)
public_key = key.publickey()
enc_data = public_key.encrypt('Bob', 32)
cipher = PKCS1_OAEP.new(key)
ciphertext = cipher.encrypt('Bob')
The two commands which are meant to encrypt 'Bob' produce these errors, and yes I now that the first way isn't very secure.
In Python 3 there is a difference between strings and bytes. PyCrypto works on bytes, so you need to give it bytes, but "Bob" is a string. You can convert a string a to bytes with a.encode(), which uses a default encoding. If you have another encoding in mind, then you need to specify it.
You can also mark a literal string as bytes by prefixing it with a b. Example: b"Bob".

Error when using zlib.compress function in Python 3.2

I'm importing zlib in my Python program. It works fine in Python 2.6 but shows an error when I try to run it in Python 3.2.
This is my code:
import zlib
s = 'sam'
print ("Your string length is",len(s))
t = zlib.compress(s)
print ("Your compressed string is",t)
print ("Your compressed string length is",len(t))
print ("Your decompressed string is",zlib.decompress(t))
print ("Crc32 is",zlib.crc32(t))
The error I get is this:
Your string length is 3
Traceback (most recent call last):
File "F:\workspace\samples\python\zip.py", line 4, in <module>
t = zlib.compress(s)
TypeError: 'str' does not support the buffer interface
But the above program works fine in Python 2.6. Should I use an alternative to zlib? Please help me.
Edit: I got it to work. It seems I needed to encode it. Here is the revised code:
import zlib
s = 'sam'
print ("Your string length is",len(s))
s=s.encode('utf-8')
t = zlib.compress(s)
print ("Your compressed string is",t)
print ("Your compressed string length is",len(t))
print ("Your decompressed string is",zlib.decompress(t))
print ("Crc32 is",zlib.crc32(t))
Th str type in Python is no longer a sequence of 8-bit characters, but a sequence of Uncode characters. You need to use the bytes type for binary data. You convert between strings and bytes by encoding/decoding.

Resources