How to fix 'str' object has no attribute 'encrypt'? - python

I'm trying to to encrypt a message using a given public key pubkey that i read off a file. When I try to run my program I get an error message stating that
'str' object has no attribute 'encrypt'.
I have already tried encoding the public key, but I am still getting the same error. Since I need to use these specific public key I cannot generate another random public key.
Following is my code:
from Crypto.PublicKey import RSA
import math
def text_to_int(text):
"""
Converts text into an integer for use in encryption.
input: text - a plaintext message
output: integer - an integer encoding text
"""
integer = 0
for char in text:
if integer > 0:
integer = integer*256
integer = integer + ord(char)
return integer
#Read public key
with open('C:\\Users\\alan9\\Downloads\\Assignement2\\Supporting_Files\\HLand_Key.pub', 'rb') as f:
read_key = f.read()
# use the PUBLIC KEY to encrypt a message:
message = "attack early next week"
message_int = text_to_int(message)
ciphertext = read_key.encrypt(message_int, None)
#Write ciphertext to file
with open('C:\\Users\\alan9\\Downloads\\Assignement2\\Supporting_Files\\cipher.txt', 'w') as f_write:
f_write.write(ciphertext)
I expect the output to return the encrypted message in a text file named cipher using the specified public key.
Any help will be appreciated!!!

Related

DSA key format not supported

I am trying to do a P2MS script.
For my script, I am saving the keys into a text file with DER format instead of the usual PEM file. Both key and signatures are saved in a text file and hexlify. Below is my code for the P2MS execution.
from Crypto.PublicKey import DSA
from Crypto.Hash import SHA256
from Crypto.Signature import DSS
from binascii import hexlify, unhexlify
import binascii
message = b"helpsmepls"
# Read scriptPubKey and scriptSig from files
with open('scriptPubKey.txt', 'r') as f:
readscriptPubKey = f.read().strip()
with open('scriptSig.txt', 'r') as f:
scriptSig = f.read().strip()
print(type(readscriptPubKey))
tempholder = readscriptPubKey.split()
# Removing the first character and last character
removeend = tempholder[1:-1]
scriptPubKey = []
# Removing front extra headings
for count, x in enumerate(removeend):
w = bytes(removeend[count][1:-1], encoding = 'utf-8')
#print(w)
scriptPubKey.append(w)
# Splitting the Signatures
signatures = scriptSig.split()
hash_obj = SHA256.new(message)
# Going through the pubkeys based on the number of signatures generated
for o, sig in enumerate(signatures):
pub_key = DSA.import_key(bytes.fromhex(scriptPubKey[o].decode("utf-8")))
hash_obj = SHA256.new(message)
verifier = DSS.new(pub_key, 'fips-183-3')
# Verifying if the Public key and signatures match, loop will break if False is encountered
if verifier.verify(hash_obj, sig):
d = True
else:
d = False
break
break
if d == True:
print("The message is authentic.")
else: print("The message is not authentic.")
Unfortunately before my code can reach the verification, it encountered an error.
Full traceback
It seems my DSA key format has an error, but I am not too sure why is it giving me that error.
I have also tried unhexlifying my input from the public key text file, but it also did not work. I have tried to hex decode the input to get the DER format of the input, but my type is still just bytes. I am not so sure how to properly import the key with the appropriate DSA key format from a txt file. I am able to do that with a PEM file but would just like to find out how to execute it with a txt file.
My expected outcome is the DSA key is imported properly and i am able to verify the public key with the signatures.

Verification failure PKCS1_PSS verifier object for Signature signed with RSA 3k and sha384.[Crypto python module]

I am trying to verify the signature file(binary file). I have RSA3k public key and the hash algorithm used is SHA384 Padding shceme used is: PSS. I used Crypto.Signature module in python. I am creating a verifier object in-order to verify the signature -->** PKCS1_PSS.new(key)**.
Below the simple code, verify_signature function takes three parameters public_key_file, message_file and signature_file and returns whether the signature is authentic or not.
Code:
def verify_signature(public_key_file, message_file, signature_file):
# Read the public key from the PEM file
# with open(public_key_file, 'rb') as f:
# key = RSA.importKey(f.read())
# construct key using the modulus file
with open(os.path.join('projectkeys', 'exponent.fws'), 'rb') as f: # open exponent file
data = f.read()
e = int(data.hex(), 16)
with open(public_key_file, 'rb') as f:
data = f.read()
n = int(data.hex(), 16)
key = RSA.construct((n, e))
with open(message_file,'rb') as f2:
message = f2.read()
with open(signature_file,'rb') as f3:
signature = f3.read()
h = SHA384.new(message)
# Verify the signature using the verifier and the hashed message
# mgf = lambda x,y : MGF1(x,y,SHA384.new(message))
verifier = PKCS1_PSS.new(key)
if verifier.verify(h, signature):
return "The signature is authentic."
else:
return "The signature is not authentic."
I tried both ways i. to read the key from the file and ii. constructed key using modulus(n) and exponent(e) values.
This verifier object is verifying correctly if the key is RSA2k and sha256. I tried to explore the mgf(mask generation function) and pass the values appropriately, but I am getting incorrect output.
If anyone has an idea why this code is failing will be really helpful. Or sharing any alternate way of verifying the signature for example using openssl.
Thanks,

how to generate a random key for AES for python py3rijndael module

import unittest
import base64
from py3rijndael import Rijndael
def test_rijndael():
key = 'qBS8uRhEIBsr8jr8vuY9uUpGFefYRL2HSTtrKhaI1tk='
print(len(key))
a=input("Please Enter Plain text: ")
plain_text=a.encode('utf-8')
rijndael = Rijndael(base64.b64decode(key), block_size=32)
padded_text = plain_text.ljust(32, b'\x1b')
cipher = rijndael.encrypt(padded_text)
cipher_text = base64.b64encode(cipher)
pl_txt=rijndael.decrypt(cipher)
pl_txt[:len(plain_text)]
return cipher_text
In the above code, I want to generate a random key for the secure private key
changing any character in the key for ex: making
key = 'qBS8uRhEIBsr8jr8vuY9uUpGFefYRL2HSTtrKhaI1tk+' or some thing else, making test to fail with invalid key size. could someone please help with this.

Implementing SHA1-HMAC with Python

I am implementing SHA1-HMAC generation for python (v 3.7) to be able to create HMAC code.
I have used an online generator to create SHA1-HMAC with the following data:
string: '123'
Secret Key: 'secret'
Digest algorithm: SHA1
I am getting this result:
b14e92eb17f6b78ec5a205ee0e1ab220fb7f86d7
However when I try to do this same with Python I am getting different results which are wrong.
import hashlib
import hmac
import base64
def make_digest(message, key):
key = bytes(key, 'UTF-8')
message = bytes(message, 'UTF-8')
digester = hmac.new(key, message, hashlib.sha1)
signature1 = digester.digest()
signature2 = base64.urlsafe_b64encode(signature1)
return str(signature2, 'UTF-8')
result = make_digest('123', 'secret')
print(result)
This code gives result:
sU6S6xf2t47FogXuDhqyIPt_htc=
What could be wrong with this code?
You should not use Base64 here. The site you link to gives you the hex values of the digest bytes. Use the HMAC.hexdigest() method to get the same value in hex in Python:
>>> key = b'secret'
>>> message = b'123'
>>> digester = hmac.new(key, message, hashlib.sha1)
>>> digester.hexdigest()
'b14e92eb17f6b78ec5a205ee0e1ab220fb7f86d7'
put differently, your code outputs the correct value, but as Base64-encoded data:
>>> digester.digest()
b'\xb1N\x92\xeb\x17\xf6\xb7\x8e\xc5\xa2\x05\xee\x0e\x1a\xb2 \xfb\x7f\x86\xd7'
>>> base64.urlsafe_b64encode(digester.digest())
b'sU6S6xf2t47FogXuDhqyIPt_htc='
and the value you generated online contains the exact same bytes as the hex digest, so we can generate the same base64 output for that:
>>> bytes.fromhex('b14e92eb17f6b78ec5a205ee0e1ab220fb7f86d7')
b'\xb1N\x92\xeb\x17\xf6\xb7\x8e\xc5\xa2\x05\xee\x0e\x1a\xb2 \xfb\x7f\x86\xd7'
>>> base64.urlsafe_b64encode(bytes.fromhex('b14e92eb17f6b78ec5a205ee0e1ab220fb7f86d7'))
b'sU6S6xf2t47FogXuDhqyIPt_htc='

Attribute error while using lambda in python

okay so here is my code so far:
import os
import time
import random
import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
from Crypto.Cipher import AES
import base64
key = 'MIICWwIBAAKBgQDN'
print('do you have a encrypted string in a file?')
fileexist = input('if so then input 1:')
if fileexist == 1:
filename = raw_input('please input path to file:')
file = open(filename,'r')
encoded = file.read()
type = type(encoded)
else:
encoded = raw_input('please enter encrypted text')
encoded = str(encoded)
BLOCK_SIZE = 16
PADDING = '{'
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
decoded = DecodeAES(key, encoded)
print(decoded)
I keep geting a attribute error on line 24 my exact error message is as bellow
AttributeError: 'str' object has no attribute 'decrpt'
I am trying to decrypt a message using AES. my encrypter works just fine using almost the exact same syntax. I dont fully understand the why the error apears. I know this is possible I have seen other post using this syntax.
Spelling issues set aside, in the code you link to, the first argument to DecodeAES is a AES.AESCipher object created with AES.new :
# create a cipher object using the random secret
cipher = AES.new(secret)
In your own code you are passing the string key, which doesn't have a decrypt method.
And FWIW this has nothing to do with the function being defined as a lambda - the function version would behave the very same way:
def DecodeAES(c, e):
return c.decrypt(base64.b64decode(e)).rstrip(PADDING)
DecodeAES("foo", "bar")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in DecodeAES
AttributeError: 'str' object has no attribute 'decrypt'
You first need to create an AES object to pass in DecodeAES.
Do it using
key = 'MIICWwIBAAKBgQDN'
cipher = AES.new(key)
Now instead of calling DecodeAES on the key, you call it on the cipher object we created with the key:
decoded = DecodeAES(cipher, encoded)
That should make your code working.

Categories