I'm trying to verify a signed message, but I keep getting the error;
AttributeError: '_io.BufferedReader' object has no attribute 'n'
I can't really figure out what causes this error
First of all, I sign the AES encrypted data and then base64 encode it.
Then a json.dump that is printed out, when running the script I pipe it to a file
def get_signature(message):
h = SHA256.new(message)
signature = pkcs1_15.new(priv_keyObj).sign(h)
return signature
ENCODING = 'utf-8'
print(json.dumps({
'EncryptedString': base64.standard_b64encode(encrypted_data).decode(ENCODING),
'SignedDataString': base64.standard_b64encode(get_signature(encrypted_data)).decode(ENCODING),
}))
I start by reading the file as json, then when I verity, I read the base64 encoded msg and start with a b64 decoding;
def verify_signature(message, signature):
h = SHA256.new(message)
try:
pkcs1_15.new(pub_key_new).verify(h, signature)
print("The signature is valid.")
except (ValueError, TypeError):
print("The signature is not valid.")
verify_signature(base64.standard_b64decode(data['EncryptedString']), base64.standard_b64decode(data['SignedDataString']))
I have tried to make this question minimal and understandable - so please tell me if I need to provide more information.
The full traceback is;
>Traceback (most recent call last):
> File "C:/PATH/Scipts/crypto/decrypt.py", line 9, in <module>
print(default_decrypt(read_json_file(filename)).decode("utf-8"))
> File "C:\PATH\Scipts\crypto\crypt_helper_new.py", line 127, in default_decrypt
verify_signature(base64.standard_b64decode(data['EncryptedString']),
base64.standard_b64decode(data['SignedDataString']))
encoded msg: <class 'str'>
> File "C:\PATH\Scipts\crypto\crypt_helper_new.py", line 65, in verify_signature
pkcs1_15.new(pub_key_new).verify(h, signature)
message: b'S\xacU\x14\xb2E\xec\x08\xc3\x83\x18\x8ey\x98\x069'
> File "C:\PATH\AppData\Local\Programs\Python\Python36\lib\site-packages\Crypto\Signature\pkcs1_15.py", line 106, in verify
modBits = Crypto.Util.number.size(self._key.n)
> AttributeError: '_io.BufferedReader' object has no attribute 'n'
You can't pass a buffer directly to that function. You should read the bytes from the file to create a key object:
pub_key_new = RSA.import_key(open('foo.pub').read())
The type of self._key (i.e. pub_key_new) should be:
<class 'Crypto.PublicKey.RSA.RsaKey'>
Related
my code us:
# init scrapy selector
response = Selector(text=content)
json_data = json.loads(script.get() for script in (re.findall(r'dataLayer\.push\(([^)]+)'),response.css('script::text'))).group(1)
print(json_data)
# debug data extraction logic
HummartScraper.parse_product(HummartScraper, '')
'
the output error is:
Traceback (most recent call last):
File "hummart2.py", line 86, in parse_product
json_data = json.loads(script.get() for script in (re.findall(r'dataLayer\.push\(([^)]+)'),response.css('script::text'))).group(1)
TypeError: findall() missing 1 required positional argument: 'string'
why is this error getting.
For a single dataLayer:
data_layer = response.css('script::text').re_first(r'dataLayer\.push\(([^)]+)')
data = json.loads(data_layer)
You can use response.css(...).re() to get a list of matches.
but this give me this type of error:
File "hummart2.py", line 88, in parse_product
data = json.loads(data_layer_raw)[1]
File "/home/danish-khan/miniconda3/lib/python3.7/json/__init__.py", line 341, in loads
raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not NoneType
I'm trying to take the string hello, encode it into hexadecimal, and then print success if the value of t is found in the encoded string.
This is what I have currently:
import codecs
t='68656c6c6df'
pkts = ("hello")
pkts1 = codecs.encode(b'hello', 'hex_codec')
if "t" in pkts1:
print ('success')
Which gives me the error:
Traceback (most recent call last):
File "C:/Users/K/.PyCharmCE2018.1/config/scratches/scratch_1.py", line 8, in <module>
if "t" in pkts1:
TypeError: a bytes-like object is required, not 'str'
python 2.x code
sdata = StringIO.StringIO(c.data)
python 3.x code
sdata = io.StringIO(c.data)
complete code
def downloadCSV(c, d):
filename = c.getFilename(d)
reqstr = c.getReqStr(d)
print(("Downloading %s ..." % (filename)))
if c.getResponse(reqstr) == -1:
return -1
sdata = io.StringIO(c.data)
z = zipfile.ZipFile(sdata)
Error :
Traceback (most recent call last):
File "xxx.py", line 166, in <module>
main(sys.argv[1:])
File "xxxx.py", line 158, in main
getMonth(c, args[1], args[2])
File "xxxx.py", line 133, in getMonth
if downloadCSV(c, d) > -1:
File "xxxx.py", line 73, in downloadCSV
sdata = io.StringIO(c.data)
TypeError: initial_value must be str or None, not bytes
right import is done for 3.x python version and the conversion for sdata should be automatically happening here ? Why this above error coming ,and what is the way to correct this error in python3.x . Tried other answers posted in this forum but nothing seeming to be working in this case.
Python 3 now makes a difference between str and bytes.
Your request returned binary data, so to be able to store it in a io object you have to create a BytesIO object not a StringIO object. So:
sdata = io.BytesIO(c.data)
Note that the code is still compatible with Python 2.
I run the script with python3 in the terminal but when I reach a certain point in it, I get the following error:
Traceback (most recent call last):
File "client.py", line 50, in <module>
client()
File "client.py", line 45, in client
s.send(bytes((msg, 'utf-8')))
TypeError: 'str' object cannot be interpreted as an integer
This is the code it refers to.
else :
# user entered a message
msg = sys.stdin.readline()
s.send(bytes((msg, 'utf-8')))
sys.stdout.write(bytes('[Me] '))
sys.stdout.flush()
I read the official documentation for bytes() and another source
https://docs.python.org/3.1/library/functions.html#bytes
http://www.pythoncentral.io/encoding-and-decoding-strings-in-python-3-x/
but I am no closer to understanding how to fix this. I realise that my msg is a string and I need an integer, but I am confused about how to convert it. Can you please help me, or direct me to a source that will help me?
Edit 1: I changed the line
s.send(bytes((msg, 'utf-8')))
to
s.send(bytes(msg, 'utf-8'))
but now I get the following error:
Traceback (most recent call last):
File "client.py", line 50, in <module>
client()
File "client.py", line 46, in client
sys.stdout.write(bytes('[Me] '))
TypeError: string argument without an encoding
Edit 2: According to #falsetru updated answer.
Using bytes literal gives me
TypeError: must be str, not bytes
Change the following line:
s.send(bytes((msg, 'utf-8')))
as:
s.send(bytes(msg, 'utf-8'))
In other words, pass a string and an encoding name instead of a passing a tuple to bytes.
UPDATE accoridng to question change:
You need to pass a string to sys.stdout.write. Simply pass a string literal:
sys.stdout.write('[Me] ')
I am trying to read an XML file from the Yahoo finance API. So far, I've tried the following:
from xml.dom.minidom import parse
#Start Get Employees
xml = urllib.request.urlopen('https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.stocks%20where%20symbol%3D%22wfc%22&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys')
dom = parse(xml.read())
numemployees = dom.getElementsByTagName('FullTimeEmployees')
numemployees = name[0].firstChild.nodeValue
#End Get Employees
However, this raises an exception:
AttributeError: 'bytes' object has no attribute 'read'
I think this is because if it doesn't recognize the string, it assumes I'm passing a byte pattern. However, I am passing a string so I don't know what the problem is here.
Full Stack Trace:
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1487, in __call__
return self.func(*args)
File "C:\Users\kylec\Desktop\dm\Mail Server Finder\mailserverfinder.py", line 25, in getServers
dom = parse(xml.read())
File "C:\Python34\lib\xml\dom\minidom.py", line 1960, in parse
return expatbuilder.parse(file)
File "C:\Python34\lib\xml\dom\expatbuilder.py", line 913, in parse
result = builder.parseFile(file)
File "C:\Python34\lib\xml\dom\expatbuilder.py", line 204, in parseFile
buffer = file.read(16*1024)
AttributeError: 'bytes' object has no attribute 'read'
xml.dom.minidom.parse is excepting a file-like object, not a bytes or str, as stated in its documentation:
xml.dom.minidom.parse(filename_or_file[, parser[, bufsize]])
Return a Document from the given input. filename_or_file may be either
a file name, or a file-like object.
So you just need to do this:
dom = parse(xml)
Because the http.client.HTTPResponse object returned by urlopen is file-like.
Kyle, sorry but your example isn't clear enough. I think this is what you expected to do.
from xml.dom.minidom import parseString
employees = urllib.urlopen('https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.stocks%20where%20symbol%3D%22wfc%22&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys').read()
dom = parseString(employees)
numemployees = dom.getElementsByTagName('FullTimeEmployees')
numemployees = numeemployees[0].firstChild.nodeValue