Python script for encrypting / decrypting suddenly doesn't work - python

I'm brushing up on public/private keypair encryption. To illustrate the concept to myself, I wrote a primitive script. It used to work just a week ago with my python client:
> Python 2.7.9 (default, Apr 2 2015, 15:33:21) [GCC 4.9.2] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
> >>>
Today, I tried to run it, and got the following error:
work#work-IdeaPad-U330p:~/projects/Script$ python example_encrypt_decrypt.py
Traceback (most recent call last):
File "example_encrypt_decrypt.py", line 9, in <module>
encrypted_message = public_key_1.encrypt(M, 24)
File "/usr/local/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 123, in __getattr__
raise AttributeError(attrname)
AttributeError: encrypt
The script I'm running is this:
from Crypto.PublicKey import RSA
import binascii
private_key_1 = RSA.generate(1024)
public_key_1 = private_key_1.publickey()
M = "Hello World."
encrypted_message = public_key_1.encrypt(M, 24)
# print binascii.hexlify(encrypted_message[0])
# The private key corresponding to the public key used
# to encrypt the message can decrypt the message.
decrypted_message = private_key_1.decrypt(encrypted_message)
print decrypted_message
# The message can not be decrypted with another
# private key.
private_key_2 = RSA.generate(1024)
print private_key_2.decrypt(encrypted_message)

Related

python - NameError on a variable declared outside class

Python newbie and learning how to use a class. I've defined a class which has a method - "create" that uses a parameter (private_key) as part of a command to create a token.
Here's the command:
jwt.encode(payload, private_key, algorithm="RS256", headers=additional_headers).decode("utf-8")
I use a function outside of the class to populate the variable private_key.
Here's the code (myToken.py):
class MyTokenMgr():
def __init__(self):
pass
def create(self, privkey, email):
<MORE CODE HERE TO CREATE TOKEN>
# Function to load key from file
def load_privkey(privkey_filename):
with open(privkey_filename, 'r') as f:
data = f.read()
return data
#Read the private local key
private_key = load_privkey('testkeys/jwt-key')
print('This is the local private key:', private_key)
Here's my problem. When I run python locally from command line. I want to test instantiation of the object. However, I get NameError and variable is not defined
:
$ python
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib.myToken import MyTokenMgr
This is the local private key: -----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEAtr454soMHt7IYU+9mM6OmtzOK/i2ajNwtybYY/fQf3vMOUt8
'''
'''
-----END RSA PRIVATE KEY-----
>>> newtoken = MyTokenMgr()
>>> newtoken.create(private_key,'test#gmail.com')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'private_key' is not defined
You can see that I printed out the variable so I can view the key and confirm its used by the variable. So why am I still getting the is not defined error?
What concept am i misunderstanding? Thanks for your help.
from lib.myToken import MyTokenMgr
You're only importing the symbol MyTokenMgr. If you want to import other symbols, you need to specify them as well when importing:
from lib.myToken import MyTokenMgr, private_key

NameError: name 'sv' is not defined while importing python module

I am facing a problem in python. Tho the error is quite common, but since i am bit new to python, unable to comprehend the source hence asking you all. There are 2 modules: session.py and objects.py.
session.py
import copy
import pymongo
import spacy
import tweepy
import objects
objects.py:
import re
def refresh (sv = sv, obj = ''):
return 0
now, in python shell, i am getting the error before even executing objects.py:
$ python
Python 2.7.13 (default, Sep 26 2018, 18:42:22)
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import session
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "session.py", line 6, in <module>
import objects
File "objects.py", line 3, in <module>
def refresh (sv = sv, obj = ''):
NameError: name 'sv' is not defined
>>>
I came from perl background to maybe missing some very common thing, but still i am able to do this:
>>> def ff(t): print t
...
In above, whitout defining t, it is working while in objects.py, how can i define sv without starting execution?

Object type <class 'str'> cannot be passed to C code - virtual environment

I am using Mac Anaconda. And I try to use the AES of Crypto. However, I face a strange problem.
I just want to excute a simple line of code:
obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
if I run the code without the virtual environment as below it is OK.
$ python
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 12:04:33)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more
information.
>>> from Crypto.Cipher import AES
>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
if I run with the virtual environment "testaes" then I got the error:
(testaes)$ python
Python 3.6.4 |Anaconda, Inc.| (default, Mar 12 2018, 20:05:31)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from Crypto.Cipher import AES
>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/AES.py", line 200, in new
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/__init__.py", line 55, in _create_cipher
return modes[mode](factory, **kwargs)
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/_mode_cbc.py", line 234, in _create_cbc_cipher
cipher_state = factory._create_base_cipher(kwargs)
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Cipher/AES.py", line 100, in _create_base_cipher
result = start_operation(c_uint8_ptr(key),
File "/Applications/anaconda3/envs/testaes/lib/python3.6/site-packages/Crypto/Util/_raw_api.py", line 109, in c_uint8_ptr
raise TypeError("Object type %s cannot be passed to C code" % type(data))
TypeError: Object type <class 'str'> cannot be passed to C code
You can see that at both time I use the the same Anaconda Python 3.6.4 and GCC4.2.1. How to solve this?
In Python 3, encode it into a bytearray:
obj = AES.new('This is a key123'.encode("utf8"), AES.MODE_CBC, 'This is an IV456'.encode("utf8"))
If you store these in variables and want to use them as (Python) strings again, just use:
key_as_bytearray.decode("utf8")
Check out this answer for further information.
from Crypto.Cipher import AES
import base64
def encrypt(text):
private_key = "xxx".encode('utf-8')
iv = "yyy".encode('utf-8')
cipher = AES.new(private_key, AES.MODE_CBC, iv)
pad = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)
encrypted = base64.b64encode( cipher.encrypt(pad(text)))
return encrypted.decode("utf-8")
This was working fine in Google Collab but It was not showing this above error in Python3 Terminal in Linux. So What I did is -
from Crypto.Cipher import AES
from base64 import b64encode
from Crypto.Util.Padding import pad, unpad
def encrypt(text):
private_key = bytes("xxx", 'utf-8')
iv = bytes("yyy", 'utf-8')
cipher = AES.new(private_key, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(pad(text.encode("UTF-8"), AES.block_size))
return b64encode(encrypted).decode('utf-8')
Just encode the key and you will get no error:
from Crypto.Cipher import AES
import base64
key = ''
cipher_text = ''
cipher_text = base64.b64decode(cipher_text)
decipher = AES.new(key.encode(), AES.MODE_ECB)
print(decipher.decrypt(cipher_text))
Python has package named pycryptodome which causes this error.just uninstall the package
sudo pip3 uninstall pycryptodome

Django test - 'HTTP_USER_AGENT' invalid keyword argument to test client

My Django unit tests have stopped working. Instantiating the Django test client now fails with the following error:
Traceback (most recent call last):
File "/vagrant/my/app/tests.py", line 43, in setUp
self.client = Client(HTTP_USER_AGENT='Mozilla/5.0')
File "/usr/local/lib/python2.6/dist-packages/Django-1.4.1-py2.6.egg/django/db/models/base.py", line 367, in __init__
raise TypeError("'%s' is an invalid keyword argument for this function" % kwargs.keys()[0])
TypeError: 'HTTP_USER_AGENT' is an invalid keyword argument for this function
They fail when I instantiate the Django test client.
from django.test.client import Client
...
class MyAppTestCase(TestCase):
base_fixtures = ['fixtures.json']
def setUp(self):
self.client = Client(HTTP_USER_AGENT='Mozilla/5.0') # fails here
self.setupSession()
self.authenticateUser()
When I run python manage.py shell and enter the following, it works fine.
vagrant#lucid32:/var/www/mytraps.com/spensa$ python manage.py shell
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.test.client import Client
>>> client = Client(HTTP_USER_AGENT='Mozilla/5.0')
>>>
Any thoughts on why it is chocking on the HTTP_USER_AGENT keyword?
I found the solution.
I had a model class named 'Client'. My models were imported after the django test Client class.
You can't fix stupid.

How to workaround Python "WindowsError messages are not properly encoded" problem?

It's a trouble when Python raised a WindowsError, the encoding of message of the exception is always os-native-encoded. For example:
import os
os.remove('does_not_exist.file')
Well, here we get an exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
WindowsError: [Error 2] 系統找不到指定的檔案。: 'does_not_exist.file'
As the language of my Windows7 is Traditional Chinese, the default error message I get is in big5 encoding (as know as CP950).
>>> try:
... os.remove('abc.file')
... except WindowsError, value:
... print value.args
...
(2, '\xa8t\xb2\xce\xa7\xe4\xa4\xa3\xa8\xec\xab\xfc\xa9w\xaa\xba\xc0\xc9\xae\xd7\xa1C')
>>>
As you see here, error message is not Unicode, then I will get another encoding exception when I try to print it out. Here is the issue, it can be found in Python issue list:
http://bugs.python.org/issue1754
The question is, how to workaround this? How to get the native encoding of WindowsError?
The version of Python I use is 2.6.
Thanks.
We have the same problem in Russian version of MS Windows: the code page of the default locale is cp1251, but the default code page of the Windows console is cp866:
>>> import sys
>>> print sys.stdout.encoding
cp866
>>> import locale
>>> print locale.getdefaultlocale()
('ru_RU', 'cp1251')
The solution should be to decode the Windows message with default locale encoding:
>>> try:
... os.remove('abc.file')
... except WindowsError, err:
... print err.args[1].decode(locale.getdefaultlocale()[1])
...
The bad news is that you still can't use exc_info=True in logging.error().
sys.getfilesystemencoding() should help.
import os, sys
try:
os.delete('nosuchfile.txt')
except WindowsError, ex:
enc = sys.getfilesystemencoding()
print (u"%s: %s" % (ex.strerror, ex.filename.decode(enc))).encode(enc)
For other purposes than printing to console you may want to change final encoding to 'utf-8'
That is just the repr() string of the same error message. Since your console already supports cp950, just print the component you want. This works on my system after reconfiguring to use cp950 in my console. I had to explicitly raise the error message since my system is English and not Chinese:
>>> try:
... raise WindowsError(2,'系統找不到指定的檔案。')
... except WindowsError, value:
... print value.args
...
(2, '\xa8t\xb2\xce\xa7\xe4\xa4\xa3\xa8\xec\xab\xfc\xa9w\xaa\xba\xc0\xc9\xae\xd7\xa1C')
>>> try:
... raise WindowsError(2,'系統找不到指定的檔案。')
... except WindowsError, value:
... print value.args[1]
...
系統找不到指定的檔案。
Alternatively, use Python 3.X. It prints repr() using the console encoding. Here's an example:
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> '系統找不到指定的檔案。'
'\xa8t\xb2\xce\xa7\xe4\xa4\xa3\xa8\xec\xab\xfc\xa9w\xaa\xba\xc0\xc9\xae\xd7\xa1C'
Python 3.1.2 (r312:79149, Mar 21 2010, 00:41:52) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> '系統找不到指定的檔案。'
'系統找不到指定的檔案。'

Categories