.pyc files and naive encryption - python

I have a fairly naive thing I want to do and I want to know if someone can answer can tell me if this is just flat out stupid. If what I am going to ask is not stupid but perhaps naive, I'd appreciate if I can get a nudge in a correct direction.
I have a file named pwds.py. Its contents are
import hashlib
class Pwds:
def __init__(self):
pass
def printGood(self,key):
y = hashlib.sha1()
y.update(key.encode('ascii'))
if y.hexdigest() == "db5f60442c78f08eefb0a2efeaa860b071c4cdae":
print("You entered the correct key!")
else:
print("Intruder!")
Then I have another file named runme.py, whose contents are
import pwds
x = input("Please type the password: ")
y = pwds.Pwds()
y.printGood(x)
x = input("Press any key to end")
The first time runme.py is run, a pwds.pyc file is created. My thought was that once the .pyc file was created, I could delete pwds.py and run runme.py as normal. Additionally, I thought the contents of pwds.py would be contained in .pyc but made unreadable since this is a "compiled" Python file. Thus, while I can delete pwds.py and successfully run runme.py, pwds.pyc is pretty much readable if I open it in, say, Notepad.
Thus, the question(s) in general: How can I keep the contents of pwds.py unreadable? What I wanted to do with the above code was to keep "secret" information in a Python file, compile it, and have its contents be accessible only if the correct key were typed. Is this approach too stupid to even consider? I didn't want to get into writing a "garbler" and a "degarbler". I thought this would be a simple and cheap solution.
Thanks for reading this! Please let me know if there is any other information I should provide.

The .pyc file simply contains the compiled python code so it doesn't need to be recompiled everytime you run your program. Thus all strings in it are still readable (you could always look at the binary contents or step through the program via the pdb debugger).
If you want to protect something in your code with a password, you have to encrypt it with strong encryption and only store the encrypted version. The users's key/password is then used to decrypt the data.

Related

PYTHON How to read txt file from folders on parent directory

I'm new to python, trying to learn and code at the same time, to test what i can do, I learned java, javascript, php, html, css, on my course, so I still remeber the basics.
I reached this problem and after hours i haven't found a solution that I can understand and like.
So this is my structure:
my structure
I want to read the test_input.txt inside the test_input.py, i want that because there are some strings for the user, and i want those strings to change based on the language. I though to write the .txt along side the .py file, but then everytime a function would generate string I would need to make all the language folders again, also if needed to add another language, I also would make various folders on every string occurency.
If possible, i want a solution that read the project inside itself to get the .txt file, because i want this project to be an .exe desktop program. Also, is pyhton good to make simple desktop apps? I'm lookin foward to learn the future languages, like I learned android in java, but I want to use kotlyn because is "better", so I cold make this project in java as a learned and did some in the past, but I want the "what will be most used on the future".
Please correct me in anything if I'm wrong, all this is more about see what I can do, and how, thanks for the help!!!
If I understand you correctly, you want to load and read the txt file in py. If this is the case, like i understood, then perhaps you want to follow this tutorial here:
https://www.pythontutorial.net/python-basics/python-read-text-file/
Also, did you try to open/load it already? If so, did you get an error? Most of the time, it is a path problem for beginners so make sure the path is setup already.
Cheers
I got this script from geeksforgeeks, it got multiple form of how to read a .txt, I am leaving you as well the documentation.
# Program to show various ways to read and
# write data in a file.
file1 = open("myfile.txt","w")
L = ["This is Delhi \n","This is Paris \n","This is London \n"]
# \n is placed to indicate EOL (End of Line)
file1.write("Hello \n")
file1.writelines(L)
file1.close() #to change file access modes
file1 = open("myfile.txt","r+")
print("Output of Read function is ")
print(file1.read())
print()
# seek(n) takes the file handle to the nth
# bite from the beginning.
file1.seek(0)
print( "Output of Readline function is ")
print(file1.readline())
print()
file1.seek(0)
# To show difference between read and readline
print("Output of Read(9) function is ")
print(file1.read(9))
print()
file1.seek(0)
print("Output of Readline(9) function is ")
print(file1.readline(9))
file1.seek(0)
# readlines function
print("Output of Readlines function is ")
print(file1.readlines())
print()
file1.close()
https://www.geeksforgeeks.org/reading-writing-text-files-python/

Run python files and change strings with 1 file

lets say i have a folder which contains the following files:
f1.py
f2.py
f3.py
in f1.py i got this code:
#O = "Random string"
print("ABCD")
#P = "Random string"
but in f2.py and f3.py i have this code:
#M = "Random string"
print("EFGH")
#Z = "Random string"
And i want to change the strings in the 'print' function in f2.py and f3.py to the string i have in print in f1.py, and run all the files in the folder after changing the strings, using f1.py
It would be best to have more context why you want to do this.
This is possible, but in 99% of the cases it's not a god idea to write self modifying code, though it can be a lot of fun.
In fact you do not really write self modifying code, but more one piece of code modifying other files. But this is also rarely to be recommended.
What's more usual is, that one script analyzes / parses f1.py, extracts the data writes some data into a file (e.g. a json file)
and f2.py and f3.py read the data from that file and do then print this data.
Is there a particular reason you want to have code, that is modifying other python files.
If you really want to have f2.py and f3.py modified, then there is another solution, which is called templating (you can for example use Jinji).
In this case you have two template files f2.py.template and f3.py.template.
you write a file parsing f1.py, extracting the data and creates f2.py from f2.py.template and the extracted data. (Same for f3.py.template and f3.py)
If you're really 100% sure, that you really want what you ask for.
Yes it is possible:
you write a script, tht opens and reads f1.py line by line, looks for the line "#O = ", then memorizes the next line.
Then it reads f2.py line by line and writes it to another file (e.g. next_version_of_f2.py). it reads in a line and writes it out until it encounters the line #M = "Random string in f2.py In this case the line will be written out, the desired print will be written out, the print line from f2.py will be read and ignored and then you read and write all the other lines.
Then you close f2.py and next_version_of_f2.py, rename f2.py into f2.py.old and rename next_version_of_f2.py to f2.py
This is certainly possible but probably inadvisable.
Editing code should typically be a separate action from executing it (even when we use a single tool that can do both, like a lot of modern IDEs).
It suggests a poor workflow. If you want f2.py to print("ABCD"), then it should be written that way.
It's confusing. In order to understand what f2.py does, you have to mentally model the entirety of f1.py and f2.py, and there's no indication of this in f2.py.
It invites all kinds of difficult-to-debug situations. What happens if f1.py is run twice at the same time? What if two different versions of f1.py are run at the same time? Or if I happen to be reading f2.py when you run f1.py? Or if I'm editing f2.py and save my changes while you're running f1.py?
It's a security problem. For f1.py to edit f2.py, the user (shell, web-server, or other surface) calling f1.py has to have edit permissions on f2.py. That means that if they can get f1.py to do something besides what you intended (specifically, if they can get their own text in place of "ABCD"), then they can get arbitrary code execution in everyone else's runtime!
Note that it's perfectly fine to have code that generates or edits other code. The problem is when a program (possibly spanning multiple files) edits its own source.
gelonida discusses some options, which are fine and appropriate for certain contexts such as managing user-specific configuration or building documents. That said, if you're familiar with functions, variables, imports, and other basics of computer science, then you may not even need a config.json file or a template engine.
Reconsider the end result you're trying to accomplish. Do some more research/reading, and if you're still stuck start a new question about the bigger-picture task.
complaints about XYZ problems are old hat, so here's how to do what you want, even though it's awful and you really shouldn't.
f1.py
import os
import re
import sys
#O = "Random string"
print("ABCD")
#P = "Random string"
selector = re.compile(
r'#([A-Z]) = \"Random string\"\nprint\(\"([A-Z]{4})\"\)\n#([A-Z]) = \"Random string\"')
template = '''#{} = "Random string"
print("{}")
#{} = "Random string"'''
own_file_name = os.path.abspath(__file__)
own_directory = os.path.dirname(own_file_name)
def read_file(name: str) -> str:
with open(name, 'r') as f:
return f.read()
find_replacement = selector.match(read_file(own_file_name))
replacement = find_replacement.group(1) if find_replacement else False
if not replacement:
sys.exit(-1)
def make_replacement(reg_match) -> str:
return template.format(reg_match.group(1), replacement, reg_match.group(3))
for dir_entry in os.listdir(own_directory):
if dir_entry.is_file():
original = read_file(dir_entry.path)
with open(dir_entry.path, 'w') as out_file:
out_file.write(selector.sub(make_replacement, original))
# this will cause an infinite loop, but you technically asked for it :)
for dir_entry in os.listdir(own_directory):
if dir_entry.is_file():
exec(read_file(dir_entry.path))
I want to be clear that the above is a joke. I haven't tested it, and I desperately hope it won't actually solve any problems for you.

How to use a python program stored in a text file?

I'm making a troubleshooting program in which I need to take a python program which is stored in a text file, but I can't use the 'import' module. To clarify this, there would be a python program stored as a '.txt' file, and in the main program I would take this text file and be able to use it as a subprogram. I've tried doing this, but I have had no clue of how to go about it, especially since I do not have much experience of Python.
Below is roughly the program. I don't know how to format it either, but here goes:
phonechoice = input("What type of phone do you have?")
if 'iphone' in phonechoice:
#here I would load a text file which contains the program for the iphone
#which asks them what problem they have with their phone and gives a solution
I'm wondering how I can do this. I thought how I could do this and maybe I could 'copy and paste' the program, line by line, into a definition, which I could then use. Would this work, and if it doesn't then in what other way could I do it?
Rename the text file to a python file, i.e. change the extension to ".py". This does not change the fact that it is a text file, just like renaming a picture.jpg file to picture.txt does not change the fact that it's an image file.
If you have some wacky requirement to import a module saved in file with a .txt extension, you can not use an import statement. But it is still possible to import like this:
import imp
my_module = imp.load_source('my_module', 'example.txt')
I am a bit reluctant to answer a "homework" type question, but I will give you some pointers on what you need to do. If I have a text file with this in it:
def main():
print("Hello")
main()
I could execute the code with the exec function like this:
with open("filename.txt") as file: #filename should be the name of the file
data = file.read()
exec(data) #this executes the code
The output would be as expected:
Hello
Hopefully this will shed some light on your problem!

Python store values into binary code

This might seem like a strange question, but I have this idea that I want to make a python script that requires a pass login. The user should be able to type in the desired pass in the beginning of the program then the code will write that into the actual source code (so no extra files are generated).
I know that this is possible by doing something like this
with open('test.py','a') as f:
f.write('\nprint "hello world"')
Running this script 3 times will generate the following code
with open('test.py','a') as f:
f.write('\nprint "hello world"')
print "hello world"
print "hello world"
print "hello world"
But I would like to make my python script work on every windows machine that doesn't have python installed. So i would have to use PyInstaller - but then how would I be able to write to the source code?
(Optional solution to my question would be an answer how to securely save then password without creating too many obscure files that frightens the end-user)
AFAIK there is no way to modify your code after it is an executable, but you can simply store the password as hash in one file (Method A) or better use a special module for it (Method B). You should never store passwords anywhere in plain text (even not in your executable)
Method A (only use this if you can't use other libraries)
The code could look like this:
# To create the password file (e.g. change password)
import hashlib
with open('password', 'wb') as f:
p = 'new password'
f.write(hashlib.sha512(p.encode('utf-8')).digest()) # hash and save password
# To check the password
import hashlib
with open('password', 'rb') as f:
p_in = # your method to read get the password from the user
p = hashlib.sha512(p_in.encode('utf-8')).digest() # create hash
if p == f.read(): # verify hash (password)
# right password
else:
# wrong password
The content of the file is the binary form of the hash.
One important thing to note is, that you should use a secure hash function (look into the article linked above) or better use Method B.
Method B (you should use this)
Here is a way more secure and even simpler version (as pointed out by user9876) with the usage of the library passlib which is for such things.
This is an example copied from the passlib documentation:
# import the context under an app-specific name (so it can easily be replaced later)
from passlib.apps import custom_app_context as pwd_context
# encrypting a password...
hash = pwd_context.encrypt("somepass")
# verifying a password...
ok = pwd_context.verify("somepass", hash)
As you can see the hashing and verification is very simple and you can configure various parameters if you want.
There are a many ways to store the hash, which all have pros and cons so you have to carefully think about them.
A simple File.
You could use the same file to store other settings of you program
If someone installs your program into C:\Program Files\ your program would probably not have the rights to store a file there (but you can use some standard directory like %APPDATA%)
You could hide the file (but if someone copies the program there is a high chance, that it will be lost)
The Windows registry. You can use the standard python winreg module.
Hidden from the user
No extra files
Only on windows
Not portable (if you copy the program to another computer the password will be lost)
Append it to the executable. This is an possibility, but it wouldn't work in your case, because you can't modify a running executable. That means you would need another program to change your main program and that would be another file. So it is the same number of files as if you use the first option, but more work.
Another think to note is, that you could have a master password or fallback password if someone (accidentally) deletes your saved password. But you should think about this, because someone who knows the master password can delete the old password and get into your program.
As you already noticed, storing data in code has more problems than it solves. The way to store "hidden" configuration would be to use _winreg (or winreg in py3) under Windows, and ConfigParser for a ~/.config/myapp.ini file under Linux and other POSIX systems. But then, most people use an .INI file in %APPDATA% under Windows too, that's hidden enough.
If you write a wrapper class that abstracts away the differences, your application code can use this uniformly as a small key/value store. More or less ready-to-use solutions are in this recipe and in kilnconfig.
Then when it comes to passwords, use py-bcrypt to securely persist them.
NEVER NEVER NEVER store passwords!!! It is just insecure!
Use the following approach instead:
make a file "passwords.pwd" (windows will not recognize the file type - good for dummy useres)
Don't store the pssword but the hashing function of the password (you can use e.g. passlib or do your own approach):
import hashlib
password = "12345" #take user input here
hashed_password = hashlib.sha512(password).hexdigest()
print hashed_password
Whenever you have to verify a password, just do the above calculation and compare the result to the strored hash value.

Saving data in Python without a text file?

I have a python program that just needs to save one line of text (a path to a specific folder on the computer).
I've got it working to store it in a text file and read from it; however, I'd much prefer a solution where the python file is the only one.
And so, I ask: is there any way to save text in a python program even after its closed, without any new files being created?
EDIT: I'm using py2exe to make the program an .exe file afterwards: maybe the file could be stored in there, and so it's as though there is no text file?
You can save the file name in the Python script and modify it in the script itself, if you like. For example:
import re,sys
savefile = "widget.txt"
x = input("Save file name?:")
lines = list(open(sys.argv[0]))
out = open(sys.argv[0],"w")
for line in lines:
if re.match("^savefile",line):
line = 'savefile = "' + x + '"\n'
out.write(line)
This script reads itself into a list then opens itself again for writing and amends the line in which savefile is set. Each time the script is run, the change to the value of savefile will be persistent.
I wouldn't necessarily recommend this sort of self-modifying code as good practice, but I think this may be what you're looking for.
Seems like what you want to do would better be solved using the Windows Registry - I am assuming that since you mentioned you'll be creating an exe from your script.
This following snippet tries to read a string from the registry and if it doesn't find it (such as when the program is started for the first time) it will create this string. No files, no mess... except that there will be a registry entry lying around. If you remove the software from the computer, you should also remove the key from the registry. Also be sure to change the MyCompany and MyProgram and My String designators to something more meaningful.
See the Python _winreg API for details.
import _winreg as wr
key_location = r'Software\MyCompany\MyProgram'
try:
key = wr.OpenKey(wr.HKEY_CURRENT_USER, key_location, 0, wr.KEY_ALL_ACCESS)
value = wr.QueryValueEx(key, 'My String')
print('Found value:', value)
except:
print('Creating value.')
key = wr.CreateKey(wr.HKEY_CURRENT_USER, key_location)
wr.SetValueEx(key, 'My String', 0, wr.REG_SZ, 'This is what I want to save!')
wr.CloseKey(key)
Note that the _winreg module is called winreg in Python 3.
Why don't you just put it at the beginning of the code. E.g. start your code:
import ... #import statements should always go first
path = 'what you want to save'
And now you have path saved as a string

Categories

Resources