OK, i was unable to find this same question anywhere.. So i apologize in advance if this has been asked before.
My need is to have a script ssh into other devices at different times, to do this I need to store a password. I don't want to use plain text or base64, but I would be OK with hashing the password and I have no issue doing that. The issue is I don't know how to get the hash to be sent to the devices as a password. It just sends the hash and the login gets denied.
This is the hash script that writes to a file:
import getpass, hashlib, os
pwf = open('hashes.txt', 'w')
password = getpass.getpass()
hashpass = hashlib.sha256(password).hexdigest()
pfw.write(hashpass)
This is the 2nd script that I can pull the hash out of the file, but its still a hash.
hashes = open('hashes.txt', 'r')
for pw in hashes:
passwrd = pw.strip()
password = passwrd
Thats all fine and dandy, but the I cant login with the hash.. Im sure im doing something fundamentally wrong here. please let me know.
Also i left out the other ssh code as I didnt think it was relevent.
The entire point of a cryptographic hash is that it isn't feasible to reverse it into the original password. If you need to send the actual password, a hash will not work for you; you'd need to use an actual encryption algorithm - but then you run into a similar problem of how you store the encryption key you're using to store the password.
Either way you need a way of securely storing data on your local system that other unauthorized users can't access. Typically this is done by using key-based ssh authentication and storing the key with permissions that make it inaccessible to other users. This essentially skips the unnecessary step of encrypting/decrypting a password and instead just uses the encryption key as the authentication mechanism for ssh.
Note that there exist Python libraries that are designed for the kind of task you're doing (sshing to remote systems and running commands automatically) - fabric is one of them.
Related
I am going to start a new python project with web scraping, data analysis and etc... This implies making some logins in emails and data websites. I would like to know how can I avoid putting plain text password in my python scripts? Because I understand this is not very secure to have your password readable somewhere.
I have found a method using cryptography library that encrypts your password and generates a secret key that can decrypt it but I think it is not a good idea because as soon as a put the secret key in the script, someone can decrypt my password.
https://www.linkedin.com/pulse/encrypt-passwords-python-scripts-lee-rock/
Also, some people say to create a file named secret.py and stores there all passwords I need. When I have to use it, I can import this file and get the password. Consequently, this is not good too because there is a file full of readables passwords.
None of all these results were not satisfying.
In my case, I would like to share my code without leaking my passwords.
I am learning python so I figured I would try to make a script that automatically sends gmail emails for me.
It needs to send a login and password to my gmail account to automatically send some emails for me.
I read some of the guides here and it seems passlib is a good choice. But I am still a bit confused about how to set it up.
I use passlib to encrypt my password
The result will be stored in a hidden file in my linux vm.
When script runs, it needs to parse that hidden file on my vm for the hased password.
Here is where I am confused, I think I need to decrypt it and before sending it out? Isn't that rather insecure? Or can I send it without decryption and hopefully gmail can decrypt it?
I am using the SMTP library.
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login(gmail_sender, gmail_passwd)
Thanks
Passlib probably isn't actually the right choice here. It's primarily concerned with one-way hashing of passwords. You'd be able to use the resulting hash to verify if a user-provided password matches your hash, but not decrypt the hash. (Older Passlib releases did have an incorrectly named .encrypt() method, but Passlib 1.7 renamed that to .hash()).
You probably want one of two things, depending on your use case:
keyring is a python interface for saving & storing passwords in an OS-controlled "wallet". It works cross-platform on windows, linux, etc.
However, it may prove awkward to use if the password is needing to be run from a script that's triggered outside of a logged-in desktop session.
In that case, you may want to encrypt the credentials you're using for storage, and pick a single password (provided at call time to your script, e.g. from command line prompt or env var) to decrypt those credentials.
cryptography is a good choice for doing something like that; it provides a number of high-level functions that don't require (too much) crypto experience, such as their fernet encryption helpers.
The starttls() call sets up an encrypted SSL/TLS connection, so the password is not being sent in cleartext. Yes you will need decrypt the password before sending it to server.login(). Alternatively you could store the password in an environment variable and read it into python, which is not as secure, but much easier to implement.
I have managed to salt and hash password using this method:
import hashlib, uuid
salt = uuid.uuid4().hex
hashed_password = hashlib.sha512(password + salt).hexdigest()
How do I reverse this process to recover the actual password?
Update: You are supposed to take a password from the user, apply the same salt and hash method to their password, and then compare it with the originally salted/hashed password to see if they match. That makes perfect sense.
You don't. Hashing is a technique which is only one way. This is the whole point of hashing.
You never store raw passwords in order to protect your user if you got a leak of information in your DB.
If you want to implement some "password recover" procedure, you need to do as everyone do, send a email to the person with a temporary link to reset password on send a new one randomly generated.
Hashing is one way as in you can only encrypt (for example) a string and then compare the user provided hash with the one your app generates.
However, there is simple-crypt and it may be what you're looking for if you want "2 way" hashing.
Good question.
First off: never send users their passwords in plaintext!!
It's considered a bad security practice for a few reasons.
If anyone gets access to a user's email account (gmail, etc), then they have the password and can hijack the user account.
Second, hashing is a one-way form of encryption where you turn the password into gibberish. The big value in hashing is that the same password will always be turned into the same gibberish: every time. This means you can do password matching without ever storing the raw password. The reason you're supposed to hash a password and not do 2-way encryption like AES-256, is that 2-way encryption requires the creation, management, and securing of encryption keys which can be hard. Hashing is just easier and more secure for the vast majority of developers.
Instead of implementing password reset stuff by sending a user their password, you should instead send a user a link to a secure page where they can reset their password with a one-time token that expires after a certain amount of time.
This way, even if an attacker gets a hold of someone's email account (gmail, etc.) -- there's only a limited amount of time they can do damage.
There are a variety of ways to do this stuff yourself, but an easy approach to getting a one-time use token you don't have to store or manage is to offload user management to a microservice like Stormpath where it takes care of all the user management for you: password reset, password storage, user profiles, authentication, encryption, hashing, etc.
If you wanted to implement something like this in a Flask web app, for instance, you'd use the Flask-Stormpath library like so:
from flask import Flask
from flask.ext.stormpath import StormpathManager
app = Flask(__name__)
app.config['STORMPATH_ENABLE_FORGOT_PASSWORD'] = True
stormpath_manager = StormpathManager(app)
app.listen(3000)
NOTE: I work at Stormpath, but these rules apply regardless of what you're using and help make any application more secure.
I'm working on a small uni project where I have a program for a single user in Python using the tkinter module. I want create a screen where they will be required to enter their password. I'm not sure how to do this and where would I store the password?
I have no experience in database but I've heard of MD5 & SHA256 and I was thinking of writing the hashed or encrypted password to a text file and then reading it but I am not sure if this is safe.
The password functionality is to prevent others from looking at the users' personal diary entries.
This answer takes the simplest route in achieving a measure of security. #J.F.Sebastian points out in comments that you can definitely explore more robust security procedures with greater encryption, but this really depends on your needs
If your goal is just to experiment and create a proof-of-concept login system, you can just go with the encryption + flat file approach. For storing a password, you probably only need SHA1 since what you are encrypting is a variation of the password, and not sensitive data itself. What I mean is that you don't care about the data itself. You only care about comparing encryption results...
First you would pick a secret character set as a "salt". Unfortunately you are using an uncompiled language, so your salt will probably live within your program. But at least the password files by themselves are not useable. ("salt" is being used here as your only secret value. In a more secure approach, the secret would be a separate key used outside of the hashing of the password+salt)
import hashlib
salt = "-WOu#p.Za,>W+6&`A63/"
user_password = "password"
sha1 = hashlib.sha1()
sha1.update(user_password + salt)
encrypted = sha1.hexdigest()
print encrypted
# 476dc4076d1c7eb43152b78e9dc20d892f660f24
You can store that encrypted sha1 value to a file. Its of no use to anyone without the secret salt value. All you will do is use this value to compare against the future sha1 value when a user authenticates
test_sha1 = hashlib.sha1(raw_input("Enter password: ") + salt).hexdigest()
# Enter password: password
print encrypted == test_sha1
# True
You never actually know their password. You only know the sha1 value derived from it plus the salt. Think of it like two guards each needing to provide a key, turned simultaneously, to open the vault.
Otherwise.... you can store this in a database, along with the salt value. The procedure would still be the same but you move the salt to a more secure location that requres auth to even query it. No matter what, your salt secret is the most prized possession.
Addressing the SHA256... Greater encryption algorithms are needed for the act of storing the real data in a tangible format that needs protection (or when creating a slower hashing process for your passwords to make brute force cracking take longer to accomplish). For instance, if you decided to store a users private diary entries, you might encrypt against their password, and only store this encrypted format either on disk or in a database. When the user authenticates, you can deliver to them the decrypted data by way of their password. You never store the password, so even you as the author of the software can't access their data without their original password.
Again, as #J.F.Sebastian points out, the more robust approach would be using a bcrypt library:
http://www.mindrot.org/projects/py-bcrypt/
I'm writing a python program which allow user to login to it. I don't want to implement my own authentication but would rather take advantage of the OS(linux) mechanism. That is, when the user is trying to sign in my app by inputing username/password pair(which should be a valid OS user), I need to authenticate the pair by the OS. How to do that ? It may need the subprocess module, yet I've tried with no luck.
Try using PAM via Python PAM or similar
That should be possible by having your script read the /etc/passwd and /etc/shadow files, which contain details about usernames and passwords on a Linux system. Do note that the script will have to have read access to the files, which depending on the situation may or may not be possible.
Here are two good articles explaining the format of those files, which should tell you everything you need to know in order to have your script read and understand them:
Understanding /etc/passwd File Format
Understanding /etc/shadow File Format
By the way, when it talks about encrypted password, it means that it has been encrypted using the DES algorithm. You'll probably need to use pyDes or another python implementation of the DES algorithm in order for your script to create an encrypted password that it can compare to the one in /etc/shadow.