Crypto is not support python 3.x? - python-3.x

when I use python3.x , run code:
with open('rsa_public_key.pem') as f:
key = f.read()
rsakey = RSA.importKey(key)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
cipher_text = base64.b64encode(cipher.encrypt(aes_key))
str1 = cipher_text
it will raise an error:
File "de_test.py", line 81, in get_login_data_inputPostString
cipher_text = base64.b64encode(cipher.encrypt(aes_key))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/Crypto/Cipher/PKCS1_v1_5.py", line 137, in encrypt
em = b('\x00\x02') + ps + bchr(0x00) + message
TypeError: can't concat str to bytes
But when I use python 2.6 , it will pass.
so crypto is not support python 3.x?

Without seeing the aes_key, it looks like you're trying to pass a str object where you should be passing a bytes object to encrypt().

Related

Converts strings of binary to binary

I have a text file and a would like to read it in binary so I can transform its content into hexadecimal characters.
Then, I need to replace '20' by '0' and '80', 'e2', '8f' by '1'.
This would create a string of 0 and 1 (basically binary).
Finally, I need to convert this binary string into ascii characters.
I'm almost finish but I struggle with the last part:
import binascii
import sys
bin_file = 'TheMessage.txt'
with open(bin_file, 'rb') as file:
file_content = file.read().hex()
file_content = file_content.replace('20', '0').replace('80', '1').replace('e2', '1').replace('8f', '1')
print(file_content)
text_bin = binascii.a2b_uu(file_content)
The last line produces an error (I do not fully understand strings/hex/binary interpretation in python):
Traceback (most recent call last):
File "binary_to_string.py", line 34, in <module>
text_bin = binascii.a2b_uu(file_content)
binascii.Error: Trailing garbage
Could you give me a hand?
I'm working on this file: blank_file
I think you're looking for something like this? Refer to comments for why I do what I did.
import binascii
import sys
bin_file = 'TheMessage.txt'
with open(bin_file, 'rb') as file:
file_content = file.read().hex()
file_content = file_content.replace('20', '0').replace('80', '1').replace('e2', '1').replace('8f', '1')
# First we must split the string into a list so we can get bytes easier.
bin_list = []
for i in range(0, len(file_content), 8): # 8 bits in a byte!
bin_list.append(file_content[i:i+8])
message = ""
for binary_value in bin_list:
binary_integer = int(binary_value, 2) # Convert the binary value to base2
ascii_character = chr(binary_integer) # Convert integer to ascii value
message+=ascii_character
print(message)
One thing I noticed while working with this is that using your solution/file, there are 2620 bits, and this does not divide into 8, so it can not properly become bytes.

I am trying to read a string encrypt it save it to a text file then read the text file read the encrypted string decrypt it in python

I am trying to read a string encrypt it save it to a text file then read the text file read the encrypted string decrypt it in python, I am using cryptography library, I think the error is because of python lists adding ["string"] at the beginning and at the end,i also tried converting the read list into binary but it takes it as b["b'key'"],any ideas
def write_key(): #creating a key
key = Fernet.generate_key()
with open("key.key", "wb") as key_file:
key_file.write(key)
def load_key(): #reading the generated key
return open("key.key", "rb").read()
data = input()
data = bytes(data,'utf-8') #you cannot encrypt str do converting it to bytes
write_key() #creating the key
key = load_key() #loading the key
f = Fernet(key)
encrypted = f.encrypt(data) #encrypting the data
print(encrypted)
file = open("encrypted.txt", "w") #writing the encrypted the data
file.write("%s\n" %(encrypted))
file.close()
with open("encrypted.txt", "r") as f: #reading the encrypted the data
rdata = [line.rstrip('\n') for line in f] #removing \n as it is added while saving the txt file
print(rdata)
key = load_key()
f = Fernet(key)
decrypted_encrypted = f.decrypt(rdata)
print(decrypted_encrypted)
Output i get:
Enter the secret message: YOUR MESSAGE
Printing the encrypted message after encryption b'gAAAAABfWdNG64dvT-tpQA1EA-zYC8lsC4hL9EoZ0e008BMIWikfafT_FOmLyjWJh2dinGG8oi6VI16XCpwB1H4AZE2sk-ZgJQ=='
Printing the encrypted message after reading it from the txt file ["b'gAAAAABfWdNG64dvT-tpQA1EA-zYC8lsC4hL9EoZ0e008BMIWikfafT_FOmLyjWJh2dinGG8oi6VI16XCpwB1H4AZE2sk-ZgJQ=='"]
Traceback (most recent call last):
File "C:\Users\Documents\Projects\temp.py", line 31, in <module>
decrypted_encrypted = f.decrypt(rdata)
File "C:\Users\anaconda3\lib\site-packages\cryptography\fernet.py", line 74, in decrypt
timestamp, data = Fernet._get_unverified_token_data(token)
File "C:\Users\anaconda3\lib\site-packages\cryptography\fernet.py", line 85, in _get_unverified_token_data
utils._check_bytes("token", token)
File "C:\Users\anaconda3\lib\site-packages\cryptography\utils.py", line 31, in _check_bytes
raise TypeError("{} must be bytes".format(name))
TypeError: token must be bytes
Data passed to decrypt should be bytes not strings. Hence this issue.
While reading and writing from encrypted.txt use respective binary mode as below.
def write_key(): #creating a key
key = Fernet.generate_key()
with open("key.key", "wb") as key_file:
key_file.write(key)
def load_key(): #reading the generated key
return open("key.key", "rb").read()
data = input()
data = bytes(data,'utf-8') #you cannot encrypt str do converting it to bytes
write_key() #creating the key
key = load_key() #loading the key
f = Fernet(key)
encrypted = f.encrypt(data) #encrypting the data
file = open("encrypted.txt", "wb") #writing the encrypted the data
file.write(encrypted)
file.close()
with open("encrypted.txt", "rb") as f: #reading the encrypted the data
rdata =f.read()
key = load_key()
f = Fernet(key)
decrypted_encrypted = f.decrypt(rdata)
print(decrypted_encrypted)

Address generation for bitcoin with Python error

I am trying to understand bitcoin with python and trying to create my own vanity address generator.
Below is a snippet of the while loop. I keep getting an error after the loop runs about 10 times. Any help would be highly appreciated. i have searched the forum and have found answers.
But they don't work. IE. i changed the
intermed = hashlib.sha256(string).digest()
a few times modifying the code but still the same result.
Traceback (most recent call last):
File "main.py", line 38, in <module>
compressed_address_base58check = bitcoin.pubkey_to_address(hex_compressed_public_key)
File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/bitcoin/mai
n.py", line 452, in pubkey_to_address
return bin_to_b58check(bin_hash160(pubkey), magicbyte) File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/bitcoin/mai
n.py", line 334, in bin_hash160
intermed = hashlib.sha256(string).digest()
TypeError: Unicode-objects must be encoded before hashing
while True:
pk = binascii.hexlify(os.urandom(32)).decode('utf-8').upper()
privkey = f"{pk:0>64}"
pub = privtopub(privkey) # Get pub addr from priv key
addr = pubtoaddr(pub) # Get the 1Btc... address
decoded_private_key = bitcoin.decode_privkey(privkey, 'hex')
wif_encoded_private_key = bitcoin.encode_privkey(decoded_private_key, 'wif')
# Add suffix '01' to indicate a compressed private Key
compressed_private_key = privkey + '01'
# generate a WIF format from the compressed private key (WIF-compressed)
wif_compressed_private_key = bitcoin.encode_privkey(bitcoin.decode_privkey(compressed_private_key, 'hex'), 'wif')
# Multiply de EC generator G with the priveate key to get a public key point
pubkey = bitcoin.fast_multiply(bitcoin.G, decoded_private_key)
# Encode as hex, prefix 04
hex_encoded_public_key = bitcoin.encode_pubkey(pubkey, 'hex')
# Compress public key, adjust prefix depending on whether y is even or odd
(public_key_x, public_key_y) = pubkey
if public_key_y % 2 == 0:
compressed_prefix = '02'
else:
compressed_prefix = '03'
hex_compressed_public_key = compressed_prefix + bitcoin.encode(public_key_x, 16)
print ('Compressed Public Key: ' + hex_compressed_public_key)
# Generate compressedd bitcoin address from compressed public key
compressed_address_base58check = bitcoin.pubkey_to_address(hex_compressed_public_key)
print ("private key: " + privkey )
print ("uncompressed address: "+ addr )
print ('Compressed address: ' + bitcoin.pubkey_to_address(hex_compressed_public_key))
C_address = bitcoin.pubkey_to_address(hex_compressed_public_key)
U_address = addr
You have to encode your hex_compressed_public_key to generate the address.
compressed_address_base58check = bitcoin.pubkey_to_address(hex_compressed_public_key.encode('utf-8'))

Trying to convert telnetenable.py to Python 3.6 in Windows 10

I have a Costco R4500 router that I am trying to open up telnet on. The older telnetenable.py script is what is needed to send a TCP packet to open it up. Then the router can be upgraded/updated, as the only release of firmware available for it from Netgear is terrible.
The new telnetenable2 using UDP packets does work on Windows 10, but does not work on this older firmware. The older exe, telnetenable, using TCP, does not run on Windows 10.
I figured out I had to install Python. Then I have to use Cryptodome instead of Crypto. And apparently Visual Studio. I am not a programmer.
Installed Python, then got the crypto error, then realized the PyCrypto package is not longer maintained, then installed PyCryptoDome, and modified the telnetenable.py somewhat. Only I am not a programmer, so I have very basic knowledge. I have read a lot on the current error I am getting, but have no idea what to do. I have looked at the script, and was hoping someone could tell me what is wrong with it.
copy of code in pastebin
# Copyright (c) 2009 Paul Gebheim...
import sys
import socket
import array
from optparse import OptionParser
from Cryptodome.Cipher import Blowfish
from Cryptodome.Hash import MD5
TELNET_PORT = 23
# The version of Blowfish supplied for the telenetenable.c implementation
# assumes Big-Endian data, but the code does nothing to convert the
# little-endian stuff it's getting on intel to Big-Endian
#
# So, since Crypto.Cipher.Blowfish seems to assume native endianness, we need
# to byteswap our buffer before and after encrypting it
#
# This helper does the byteswapping on the string buffer
def ByteSwap(data):
a = array.array('i')
if(a.itemsize < 4):
a = array.array('L')
if(a.itemsize != 4):
print("Need a type that is 4 bytes on your platform so we can fix the data!")
exit(1)
a.fromstring(data)
a.byteswap()
return a.tostring()
def GeneratePayload(mac, username, password=""):
# Pad the input correctly
assert(len(mac) < 0x10)
just_mac = mac.ljust(0x10, "\x00")
assert(len(username) <= 0x10)
just_username = username.ljust(0x10, "\x00")
assert(len(password) <= 0x10)
just_password = password.ljust(0x10, "\x00")
cleartext = (just_mac + just_username + just_password).ljust(0x70, '\x00')
md5_key = MD5.new(cleartext).digest()
payload = ByteSwap((md5_key + cleartext).ljust(0x80, "\x00"))
secret_key = "AMBIT_TELNET_ENABLE+" + password
return ByteSwap(Blowfish.new(secret_key, 1).encrypt(payload))
def SendPayload(ip, payload):
for res in socket.getaddrinfo(ip, TELNET_PORT, socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_IP):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except socket.error as msg:
s = None
continue
try:
s.connect(sa)
except socket.error as msg:
s.close()
s= None
continue
break
if s is None:
print ("Could not connect to '%s:%d'") % (ip, TELNET_PORT)
else:
s.send(payload)
s.close()
print ("Sent telnet enable payload to '%s:%d'") % (ip, TELNET_PORT)
def main():
args = sys.argv[1:]
if len(args) < 3 or len(args) > 4:
print ("usage: python telnetenable.py <ip> <mac> <username> [<password>]")
ip = args[0]
mac = args[1]
username = args[2]
password = ""
if len(args) == 4:
password = args[3]
payload = GeneratePayload(mac, username, password)
SendPayload(ip, payload)
main()
md5_key = MD5.new(cleartext).digest()
This is where I get the error:
Traceback (most recent call last):
File "telnetenable.py", line 113, in <module>
main()
File "telnetenable.py", line 110, in main
payload = GeneratePayload(mac, username, password)
File "telnetenable.py", line 64, in GeneratePayload
md5_key = MD5.new(cleartext).digest()
File "C:\Users\farme\AppData\Local\Programs\Python\Python36\lib\site-packages\Cryptodome\Hash\MD5.py", line 47, in __init__
self._h = _hash_new(*args)
TypeError: Unicode-objects must be encoded before hashing
It looks to me that the arguments you are passing to the script are in unicode and the MD5 object wants it encoded prior to processing it. I think the encoding will put one symbol per byte rather than allowing any confusion that any multi-byte characters might create if there is also a single byte option for that character.
Try something this:
md5_key = MD5.new(cleartext.encode('utf-8)).digest()

Skipping elif statement?

Am trying to create a simple encryption/decryption using pycryptodome but keeping getting the following error:
ValueError: Error 3 while encrypting in CBC mode
after some digging I saw that you get this error if there is not enough data to encrypt, as in there is no padding in effect. The thing is that I've added a padding function. After debugging it seems as if my code literally skips the padding part completely and causes this error. What am I doing wrong?
import os, random
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
def encrypt(key, filename):
chunksize = 64*1024
outputfile = filename + "(encrypted)"
filesize = str(os.path.getsize(filename)).zfill(16)
IV =''
for i in range(16):
IV += chr(random.randint(0, 0xFF))
encryptor = AES.new(key, AES.MODE_CBC, IV.encode("latin-1"))
with open(filename, 'rb') as infile:
with open(outputfile, 'wb') as outfile:
outfile.write(filesize.encode("latin-1"))
outfile.write(IV.encode("latin-1"))
while True:
chunk = infile.read(chunksize)
print(len(chunk))
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - (len(chunk) % 16))
outfile.write(encryptor.encrypt(chunk))
def decrypt(key, filename):
chunksize = 64 *1024
outputfile = filename[:11]
with open(filename, 'rb') as infile:
filesize = int(infile.read(16))
IV = infile.read(16)
decryptor = AES.new(key, AES.MODE_CBC, IV.encode("latin-1"))
with open(outputfile, 'wb') as outfile:
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
outfile.write(decryptor.decrypt(chunk))
outfile.truncate(filesize)
def getkey (password):
hasher = SHA256.new(password.encode("latin-1"))
return hasher.digest()
def main():
choice = input ("do you want to [E]ncrypt of [D]ecrypt?")
if choice == 'E':
filename = input("File to encrypt >")
password = input("Password >")
encrypt(getkey(password), filename)
print("Encryption done!")
elif choice == 'D':
filename = input("File to Decrypt >")
password = input("Password >")
decrypt(getkey(password), filename)
print("Decryption done!")
else:
print("No option selected")
if __name__ == '__main__':
main()
*I am using python 3.6
EDIT:
Here are the full console output when I run the code:
C:\Users\itayg\AppData\Local\Programs\Python\Python36\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2017.1.2\helpers\pydev\pydevd.py" --multiproc --qt-support --client 127.0.0.1 --port 21111 --file C:/Users/itayg/PycharmProjects/PyCrypto/encrypt.py
Connected to pydev debugger (build 171.4249.47)
pydev debugger: process 12876 is connecting
do you want to [E]ncrypt of [D]ecrypt?E
File to encrypt >grades.jpg
Password >123
65536
49373
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm Community Edition 2017.1.2\helpers\pydev\pydevd.py", line 1585, in <module>
globals = debugger.run(setup['file'], None, None, is_module)
File "C:\Program Files\JetBrains\PyCharm Community Edition 2017.1.2\helpers\pydev\pydevd.py", line 1015, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "C:\Program Files\JetBrains\PyCharm Community Edition 2017.1.2\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/itayg/PycharmProjects/PyCrypto/encrypt.py", line 66, in <module>
main()
File "C:/Users/itayg/PycharmProjects/PyCrypto/encrypt.py", line 55, in main
encrypt(getkey(password), filename)
File "C:/Users/itayg/PycharmProjects/PyCrypto/encrypt.py", line 29, in encrypt
outfile.write(encryptor.encrypt(chunk))
File "C:\Users\itayg\AppData\Local\Programs\Python\Python36\lib\site-packages\pycryptodome-3.4.6-py3.6-win-amd64.egg\Crypto\Cipher\_mode_cbc.py", line 167, in encrypt
raise ValueError("Error %d while encrypting in CBC mode" % result)
ValueError: Error 3 while encrypting in CBC mode
Ok, let's fix a few things that are wrong with your code. First the most obvious one - your padding would break on Python 3.5+ (and your user 'menu' would break on 2.x) because infile.read() would give you bytes array so trying to add a string formed by chunk += ' ' * (16 - (len(chunk) % 16)) would result in an error. You would need to convert your whitespace pad to bytes array first: chunk += b' ' * (16 - (len(chunk) % 16))
But whitespace padding like this is a bad idea - when you're later decrypting your file how will you know how much, if any, padding you've added? You need to store this somewhere - and you do in the 'header' via the filesize value, telling a potential attacker how exactly big is your file and how much padding was added opening you to a padding oracle attack (which is possible with the bellow code so do not use it for passing messages without adding a proper MAC to it).
There are plenty of robust padding schemes that you can use - I personally prefer PKCS#7 which is simply padding your uneven block or adding a whole new block with n number of bytes with the value of n - that way, after decryption, you can pick the last byte from your block and know exactly how many bytes were padded so you can strip them. So, replace your encryption portion with:
def encrypt(key, filename):
outputfile = filename + "(encrypted)"
chunksize = 1024 * AES.block_size # use the cipher's defined block size as a multiplier
IV = bytes([random.randint(0, 0xFF) for _ in range(AES.block_size)]) # bytes immediately
encryptor = AES.new(key, AES.MODE_CBC, IV)
with open(filename, 'rb') as infile:
with open(outputfile, 'wb') as outfile:
outfile.write(IV) # write the IV
padded = False
while not padded: # loop until the last block is padded
chunk = infile.read(chunksize)
chunk_len = len(chunk)
# if no more data or the data is shorter than the required block size
if chunk_len == 0 or chunk_len % AES.block_size != 0:
padding = AES.block_size - (chunk_len % AES.block_size)
chunk += bytes([padding]) * padding
# on Python 2.x replace with: chunk += chr(padding_len) * padding_len
padded = True
outfile.write(encryptor.encrypt(chunk))
I've also changed your chunksize to match the block size you're using (multiples of AES.block_size) - it just happens that 64 is a multiple of 16 but you should pay attention to those things.
Now that we have the encryption sorted out, the decryption is all this but in reversal - decrypt all blocks, read the last byte of the last block and remove n amount of bytes from behind matching the value of the last byte:
def decrypt(key, filename):
outputfile = filename[:-11] + "(decrypted)"
chunksize = 1024 * AES.block_size # use the cipher's defined block size as a multiplier
with open(filename, 'rb') as infile:
IV = infile.read(AES.block_size)
decryptor = AES.new(key, AES.MODE_CBC, IV)
with open(outputfile, 'wb') as outfile:
old_chunk = b'' # stores last chunk, needed for reading data with a delay
stripped = False
while not stripped: # delayed loop until the last block is stripped
chunk = decryptor.decrypt(infile.read(chunksize)) # decrypt as we read
if len(chunk) == 0: # no more data
padding = old_chunk[-1] # pick the padding value from the last byte
if old_chunk[-padding:] != bytes([padding]) * padding:
raise ValueError("Invalid padding...")
old_chunk = old_chunk[:-padding] # strip the padding
stripped = True
outfile.write(old_chunk) # write down the 'last' chunk
old_chunk = chunk # set the new chunk for checking in the next loop

Resources