Python密码保护
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18569784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python Password Protection
提问by Chris Aung
I am a beginner so if this question sounds stupid, please bear with me.
我是初学者,所以如果这个问题听起来很愚蠢,请耐心等待。
I am wondering that when we write code for username/password check in python, if it is not compiled to exe ie script state
, won't people will easily open the file and remove the code potion that is doing the password check?
我想知道当我们在python中编写用户名/密码检查代码时,如果不编译为exe ie script state
,人们会不会轻松打开文件并删除进行密码检查的代码药水?
I am assuming that the whole program is entirely written in python
, no C
or C++
.
我假设整个程序完全是用python
、没有C
或C++
.
Even if I use a program like py2exe
it can be easily decompiled back to source code. So, does that mean it is useless to do a password check?
即使我使用像py2exe
它这样的程序也可以很容易地反编译回源代码。那么,这是否意味着进行密码检查没有用?
How do professional programmers cope with that?
专业程序员如何应对?
采纳答案by Mark R. Wilkins
Edit: Your revised question makes clear that you're concerned about people editing the code to bypass a password check. Yes, that is quite possible. You can deliver your code in .pyc form, but that won't necessarily prevent someone from decompiling and altering it. Unfortunately, Python's just not designed to prevent code alteration. The best you can do is perform some kind of authentication transaction with a secure server, so that no matter how someone alters the code, they can't bypass that step. Depending on your exact application, that might be overkill.
编辑:您修改后的问题清楚地表明您担心人们编辑代码以绕过密码检查。是的,这很有可能。您可以以 .pyc 形式交付您的代码,但这不一定会阻止某人反编译和更改它。不幸的是,Python 并不是为了防止代码更改而设计的。您能做的最好的事情是使用安全服务器执行某种身份验证事务,这样无论有人如何更改代码,他们都无法绕过该步骤。根据您的确切应用程序,这可能是矫枉过正。
The problem of how to manage password authentication is a tricky security problem on which people spend entire careers. However, here's some information about it, that assumes that you're trying to roll your own password authentication from scratch:
如何管理密码认证是一个棘手的安全问题,人们的整个职业生涯都在解决这个问题。但是,这里有一些关于它的信息,假设您正在尝试从头开始进行自己的密码身份验证:
Even for casual password protection, as a general rule, user passwords are not stored in a plaintext form. Instead, usually a reliable one-way hash function is used to create a bit pattern that doesn't resemble the password. When a password is entered, the same hash function is applied and the bit patterns are compared. If they're the same, the likelihood is quite high that the password was entered correctly.
即使对于临时密码保护,作为一般规则,用户密码也不会以明文形式存储。相反,通常使用可靠的单向哈希函数来创建与密码不同的位模式。输入密码时,将应用相同的散列函数并比较位模式。如果它们相同,则密码输入正确的可能性很高。
What constitutes a "reliable" hash function is tricky. Several are in common use, and some of the common hash functions are susceptible to known exploits.
什么构成“可靠”的散列函数是棘手的。有几个是常用的,一些常见的散列函数容易受到已知漏洞的影响。
Noelkd provides some code that demonstrates this approach, although MD5, which his code uses, is (I believe) one that's been compromised to an extent that there are better choices out there. This article also offers some code to do something similar:
Noelkd 提供了一些演示这种方法的代码,尽管他的代码使用的 MD5(我相信)已经被破坏到有更好的选择的程度。本文还提供了一些代码来做类似的事情:
Authentication of Users and Passwords in Python
If your concern is storing the actual password that you have to pass to the SQLite database in plaintext, that's a different problem. Most of the time, I've seen such passwords stored in plaintext in either scripts or a configuration file, and the application is structured in such a way that compromising that password is a matter of modest risk.
如果您关心的是存储必须以明文形式传递给 SQLite 数据库的实际密码,那是另一个问题。大多数情况下,我看到此类密码以明文形式存储在脚本或配置文件中,并且应用程序的结构方式使得破解该密码的风险不大。
回答by Noelkd
You can check the hash of what a user has entered vs the hash of your password to check if the user has entered the correct password, I have made a very simple example to show this:
您可以检查用户输入的哈希值与密码的哈希值,以检查用户是否输入了正确的密码,我做了一个非常简单的示例来说明这一点:
""" Python Password Check """
import hashlib
import sys
password = "2034f6e32958647fdff75d265b455ebf"
def main():
# Code goes here
print "Doing some stuff"
sys.exit(0)
while True:
input = raw_input("Enter password: ")
if hashlib.md5(input).hexdigest() == password:
print "welcome to the program"
main()
else:
print "Wrong Password"
In the example the hashed password is "secretpassword"
which hashes to "2034f6e32958647fdff75d265b455ebf"
so as you can see even if the source code is decompiled you can still only see the hash of the password rather than the plan text of the password.
在示例中,散列密码是"secretpassword"
散列到的,"2034f6e32958647fdff75d265b455ebf"
因此您可以看到即使源代码被反编译,您仍然只能看到密码的散列而不是密码的计划文本。
To give this a bit of an update for 2016, currently if your hashing passwords in python you should be looking at one of the three following libs:
为了对 2016 年进行一些更新,目前如果您在 python 中散列密码,您应该查看以下三个库之一:
passlib
密码库
>>> # import the hash algorithm
>>> from passlib.hash import sha256_crypt
>>> # generate new salt, and hash a password
>>> hash = sha256_crypt.encrypt("toomanysecrets")
>>> hash
'$rounds=80000$zvpXD3gCkrt7tw.1$QqeTSolNHEfgryc5oMgiq1o8qCEAcmye3FoMSuvgToC'
>>> # verifying the password
>>> sha256_crypt.verify("toomanysecrets", hash)
True
>>> sha256_crypt.verify("joshua", hash)
False
Example lifted from here
从这里举起的例子
bcrypt
加密
import bcrypt
password = b"super secret password"
# Hash a password for the first time, with a certain number of rounds
hashed = bcrypt.hashpw(password, bcrypt.gensalt(14))
# Check that a unhashed password matches one that has previously been
# hashed
if bcrypt.hashpw(password, hashed) == hashed:
print("It Matches!")
else:
print("It Does not Match :(")
django-scrypt
django-scrypt
回答by Joyfulgrind
Let's start with the basic now, shall we? While doing the login credential password encryption, we should always do one way encryption. One way encryption means, you can't decrypt the text once it's encrypted. There'a encryption called md5
which are only one way encryption.
现在让我们从基础开始吧?在进行登录凭证密码加密时,我们应该始终进行单向加密。加密的一种方式意味着,一旦加密,您就无法解密文本。有一种加密称为md5
这只是一种加密方式。
There's already a library available for it in Python called hashlib
.
Python 中已经有一个可用的库,名为hashlib
.
From the python docs:
从 python 文档:
>>> import hashlib
>>> m = hashlib.md5()
>>> m.update("Nobody inspects")
>>> m.update(" the spammish repetition")
>>> m.digest()
'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
>>> m.digest_size
16
>>> m.block_size
64
More on this: http://docs.python.org/2/library/hashlib.html?highlight=hashlib#hashlib
更多相关信息:http: //docs.python.org/2/library/hashlib.html?highlight=hashlib#hashlib
回答by rlms
If you are doing the checking on a user's machine, they can edit the code how they like, pretty much no matter what you do. If you need security like this then the code should be run somewhere inaccessible, for instance a server. "Don't trust the client" is an important computer security principle.
如果您在用户的机器上进行检查,他们几乎可以根据自己的喜好编辑代码,无论您做什么。如果您需要这样的安全性,那么代码应该在无法访问的地方运行,例如服务器。“不信任客户端”是一项重要的计算机安全原则。
I think what you want to do is make a server script that can only be accessed by a password being given to it by the client program. This server program will function very much like the example code given in other answers: when a new client is created they send a plaintext password to the server which puts it through a one-way encryption, and stores it. Then, when a client wants to use the code that is the main body of your program, they send a password. The server puts this through the one-way encryption, and sees if it matches any stored, hashed passwords. If it does, it executes the code in the main body of the program, and sends the result back to the user.
我认为您想要做的是制作一个只能通过客户端程序提供给它的密码才能访问的服务器脚本。该服务器程序的功能与其他答案中给出的示例代码非常相似:创建新客户端时,它们会向服务器发送一个明文密码,服务器对其进行单向加密并存储它。然后,当客户端想要使用作为程序主体的代码时,他们会发送密码。服务器将其通过单向加密,并查看它是否与任何存储的散列密码匹配。如果是,它会执行程序主体中的代码,并将结果发送回用户。
On a related topic, the other answers suggest using the md5
algorithm. However, this is not the most secure algorithm - while secure enough for many purposes, the hashlib
module in the standard library gives other, more secure algorithms, and there is no reason not to use these instead.
在相关主题上,其他答案建议使用该md5
算法。然而,这并不是最安全的算法——虽然对于许多目的来说足够安全hashlib
,但标准库中的模块提供了其他更安全的算法,没有理由不使用这些算法。
回答by Lennart Regebro
On a server only server administrators should have the right to change the code. Hence, to change the code you have to have administrator access, and if you do, then you can access everything anyway. :-)
在服务器上,只有服务器管理员才有权更改代码。因此,要更改代码,您必须具有管理员访问权限,如果您这样做了,那么无论如何您都可以访问所有内容。:-)
The same goes for a client program. If the only security is the password check, you don't need to get around the password check, you can just read the data files directly.
客户端程序也是如此。如果唯一的安全性是密码检查,则无需绕过密码检查,直接读取数据文件即可。
In both cases, to prevent people that has access to the files from reading those files a password check is not enough. You have to encrypt the data.
在这两种情况下,要防止有权访问文件的人读取这些文件,仅检查密码是不够的。您必须对数据进行加密。
回答by Terrel Shumway
To protect data stored on the client machine, you have to encrypt it. Period.
要保护存储在客户端计算机上的数据,您必须对其进行加密。时期。
If you trust an authorized user, you can use a password-based encryption key (many other answers on Stack Exchange address this), and hope that he is smart enough to protect his computer from malware.
如果您信任授权用户,您可以使用基于密码的加密密钥(Stack Exchange 上的许多其他答案解决了这个问题),并希望他足够聪明,可以保护他的计算机免受恶意软件的侵害。
If you don'ttrust the authorized user (a.k.a. DRM) you are just plain out of luck -- find another project.;-)
如果您不信任授权用户(又名 DRM),那您就是运气不好——找另一个项目。;-)
回答by James Mccannon
I have spend the last couple of days refining this and running it through password crackers and it seems to be holding up pretty strong.
在过去的几天里,我一直在完善它并通过密码破解程序运行它,它似乎非常强大。
Here is my code for you to look at:
这是我的代码供您查看:
import time
import os
import random
import string
passwordScore = 0
def optionOne():
global passwordScore
#Code for checking a password
os.system('cls')
print('Option One has been selected')
password = input('Please type in your password here: ')
#Password check begins
if (len(password) > 7) and (password.isspace() == False):
#Check for capitalisation
for p in password:
if p.isupper() == True:
passwordScore += 1
else:
pass
passwordScore += 2
for s in string.punctuation:
#Beginning test for special letters
for p in password:
if s == p:
passwordScore += 1
else:
pass
else:
pass
# Returning results to the user
if passwordScore >= 5:
print('Your password is safe enough to use')
time.sleep(2)
elif passwordScore == 3:
print('We believe your password could be safer')
time.sleep(2)
else:
print('Your password is not safe enough to use')
print('using this password may place your data at risk')
time.sleep(2)
def optionTwo():
#Code for creating a password at random
print('Option Two has been selected')
chars = string.ascii_uppercase + string.ascii_lowercase + string.digits + string.punctuation
size = random.randint(8, 12)
newPassword = ''.join(random.choice(chars) for x in range(size))
print(newPassword)
def start():
print('Option 1: Check my passsword')
print('Option 2: Create a password')
option = input('Please chose your option here [ENTER]: ')
if option == '1':
#Option 1 has been selected
return optionOne()
elif option == '2':
#Option 2 has been selected
return optionTwo()
else:
#An error has occured
print('You have not selected a valid option')
time.sleep(1)
os.system('cls')
return start()
for i in range(1):
start()
This should do the job for almost everything as long as you tweak it to your needs!!
只要您根据需要对其进行调整,这几乎可以完成所有工作!!