我是初学者所以如果这个问题听起来很愚蠢,请耐心等待。
我想知道当我们在python中编写用户名/密码检查代码时,如果它没有编译为exe ie script state
,那么人们不会轻易打开文件并删除正在执行的代码药水密码检查?
我假设整个程序完全用python
,C
或C++
编写。
即使我使用像py2exe
这样的程序,它也可以很容易地反编译回源代码。那么,这是否意味着进行密码检查毫无用处?
专业程序员如何应对?
答案 0 :(得分:5)
您可以检查用户输入的哈希值与密码的哈希值,以检查用户是否输入了正确的密码,我已经做了一个非常简单的示例来说明这一点:
""" 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"
在示例中,散列密码为"secretpassword"
,其散列为"2034f6e32958647fdff75d265b455ebf"
,因此您可以看到即使源代码已反编译,您仍然只能看到密码的散列而不是计划文本密码。
为了对2016进行一些更新,目前如果您在python中使用散列密码,您应该查看以下三个库中的一个:
>>> # import the hash algorithm
>>> from passlib.hash import sha256_crypt
>>> # generate new salt, and hash a password
>>> hash = sha256_crypt.encrypt("toomanysecrets")
>>> hash
'$5$rounds=80000$zvpXD3gCkrt7tw.1$QqeTSolNHEfgryc5oMgiq1o8qCEAcmye3FoMSuvgToC'
>>> # verifying the password
>>> sha256_crypt.verify("toomanysecrets", hash)
True
>>> sha256_crypt.verify("joshua", hash)
False
取自here
的示例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 :(")
答案 1 :(得分:5)
编辑:您修改过的问题表明您关注人们编辑代码以绕过密码检查。是的,这很有可能。您可以以.pyc格式提供代码,但这不一定会阻止某人反编译和更改它。不幸的是,Python并不是为防止代码更改而设计的。您可以做的最好的事情是使用安全服务器执行某种身份验证事务,这样无论有人如何更改代码,他们都无法绕过该步骤。根据您的具体应用,这可能有点过分。
如何管理密码身份验证的问题是人们花费整个职业生涯的棘手安全问题。但是,这里有一些关于它的信息,假设您正在尝试从头开始自己的密码验证:
即使是临时密码保护,作为一般规则,用户密码也不以明文形式存储。相反,通常使用可靠的单向散列函数来创建与密码不相似的位模式。输入密码时,将应用相同的散列函数并比较位模式。如果它们相同,则输入密码的可能性非常高。
什么构成了可靠的"哈希函数很棘手。有几个是常用的,一些常见的哈希函数容易受到已知漏洞的影响。
Noelkd提供了一些演示这种方法的代码,尽管他的代码使用的MD5是(我相信)已被妥协的程度,以至于有更好的选择。本文还提供了一些类似的代码:
Authentication of Users and Passwords in Python
如果您关注的是存储您必须以纯文本格式传递给SQLite数据库的实际密码,那就是另一个问题。大多数时候,我已经看到这些密码以明文形式存储在脚本或配置文件中,并且应用程序的结构使得密码泄密的风险很小。
答案 2 :(得分:4)
如果您正在检查用户的计算机,他们可以编辑他们喜欢的代码,几乎无论您做什么。如果您需要这样的安全性,那么代码应该在无法访问的地方运行,例如服务器。 “不信任客户”是一项重要的计算机安全原则。
我认为您要做的是创建一个服务器脚本,只能通过客户端程序提供给它的密码来访问。此服务器程序的功能与其他答案中给出的示例代码非常相似:创建新客户端时,它们会向服务器发送明文密码,通过单向加密将其存储起来。然后,当客户想要使用作为程序主体的代码时,他们会发送密码。服务器通过单向加密进行此操作,并查看它是否与任何存储的哈希密码匹配。如果是,则执行程序主体中的代码,并将结果发送回用户。
在相关主题上,其他答案建议使用md5
算法。但是,这不是最安全的算法 - 虽然安全性足以用于多种用途,但标准库中的hashlib
模块提供了其他更安全的算法,并且没有理由不使用这些算法。
答案 3 :(得分:2)
在服务器上,只有服务器管理员才有权更改代码。因此,要更改代码,您必须具有管理员访问权限,如果这样做,则无论如何都可以访问所有内容。 : - )
客户端程序也是如此。如果唯一的安全性是密码检查,则无需绕过密码检查,您只需直接读取数据文件即可。
在这两种情况下,为了防止有权访问这些文件的人阅读这些文件,密码检查是不够的。您必须加密数据。
答案 4 :(得分:1)
现在让我们从基础开始,好吗?在进行登录凭证密码加密时,我们应该始终采用单向加密方式。加密的一种方式是,一旦加密就无法解密文本。有一种称为md5
的加密,它只是单向加密。
在Python中已经有一个名为hashlib
的库。
来自python docs:
>>> 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
更多相关信息:http://docs.python.org/2/library/hashlib.html?highlight=hashlib#hashlib
答案 5 :(得分:0)
要保护客户端计算机上存储的数据,您必须对其进行加密。周期。
如果您信任授权用户,则可以使用基于密码的加密密钥(Stack Exchange上的许多其他答案解决此问题),并希望他足够聪明以保护其计算机免受恶意软件攻击。
如果你不信任授权用户(a.k.a. DRM),你就是运气不好 - 找另一个项目。; - )
答案 6 :(得分:0)
一种方法是以任何算法的哈希形式存储密码,并检查给定密码的哈希是否等于存储的密码哈希。
第二种方法可能是使用“ cat”之类的密码并将其转换为ascii并加起来并存储和。然后,您可以将给定密码的ascii和与您存储的密码进行比较。
或者您可以将两者结合!也许还可以对ascii总和进行哈希运算,并比较给定密码的ascii sun哈希值。
这些是我至少知道的三种方式。而且您可以在python中使用chr或ord默认函数来反复转换为ascii。您可以使用hashlib进行哈希处理。
答案 7 :(得分:-1)
我花了最近几天的时间来改进这个并通过密码破解程序运行它,它似乎非常强大。
以下是我的代码:
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()
只要你根据自己的需要进行调整,这几乎应该可以完成所有工作!!