我是初学者,所以如果这个问题听起来很愚蠢,请多多包涵。
我想知道,当我们在 python 中编写用户名/密码检查代码时,如果它没有编译为 exe ie script state
,人们不会轻易打开文件并删除正在执行密码检查的代码药水吗?
我假设整个程序完全是用python
, no C
or编写的C++
。
即使我使用类似的程序py2exe
,也可以轻松地将其反编译回源代码。那么,这是否意味着进行密码检查是没有用的?
专业程序员如何应对呢?
我是初学者,所以如果这个问题听起来很愚蠢,请多多包涵。
我想知道,当我们在 python 中编写用户名/密码检查代码时,如果它没有编译为 exe ie script state
,人们不会轻易打开文件并删除正在执行密码检查的代码药水吗?
我假设整个程序完全是用python
, no C
or编写的C++
。
即使我使用类似的程序py2exe
,也可以轻松地将其反编译回源代码。那么,这是否意味着进行密码检查是没有用的?
专业程序员如何应对呢?
编辑:您修改后的问题清楚地表明您担心人们编辑代码以绕过密码检查。是的,这很有可能。您可以以 .pyc 形式交付代码,但这并不一定会阻止某人反编译和更改它。不幸的是,Python 的设计初衷并不是为了防止代码更改。您能做的最好的事情是使用安全服务器执行某种身份验证事务,这样无论有人如何更改代码,他们都无法绕过该步骤。根据您的确切应用程序,这可能是矫枉过正。
如何管理密码认证的问题是一个棘手的安全问题,人们将整个职业生涯都花在这个问题上。但是,这里有一些关于它的信息,假设您正在尝试从头开始滚动自己的密码身份验证:
即使对于临时密码保护,作为一般规则,用户密码也不会以明文形式存储。相反,通常使用可靠的单向哈希函数来创建与密码不相似的位模式。输入密码时,应用相同的散列函数并比较位模式。如果它们相同,则密码输入正确的可能性很高。
构成“可靠”散列函数的内容很棘手。有几个是常用的,一些常见的散列函数容易受到已知漏洞的影响。
Noelkd 提供了一些代码来演示这种方法,尽管他的代码使用的 MD5 是(我相信)在一定程度上受到了损害,因此有更好的选择。本文还提供了一些代码来做类似的事情:
如果您关心的是存储必须以明文形式传递给 SQLite 数据库的实际密码,那就是另一个问题了。大多数时候,我看到过这样的密码以明文形式存储在脚本或配置文件中,并且应用程序的结构使得泄露密码的风险不大。
您可以检查用户输入内容的哈希值与密码的哈希值,以检查用户是否输入了正确的密码,我做了一个非常简单的示例来说明这一点:
""" 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
从这里举起的例子
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 :(")
如果您在用户的机器上进行检查,他们可以按照自己喜欢的方式编辑代码,几乎不管您做什么。如果您需要这样的安全性,那么代码应该在无法访问的地方运行,例如服务器。“不要信任客户端”是重要的计算机安全原则。
我认为您要做的是制作一个服务器脚本,该脚本只能通过客户端程序提供的密码访问。该服务器程序的功能与其他答案中给出的示例代码非常相似:创建新客户端时,它们向服务器发送明文密码,服务器对其进行单向加密并存储它。然后,当客户想要使用作为程序主体的代码时,他们会发送密码。服务器将其通过单向加密,并查看它是否与任何存储的散列密码匹配。如果是,它将执行程序主体中的代码,并将结果发送回用户。
在相关主题上,其他答案建议使用该md5
算法。然而,这不是最安全的算法——虽然对于许多用途来说足够安全,hashlib
但标准库中的模块提供了其他更安全的算法,没有理由不使用这些算法。
在服务器上,只有服务器管理员才有权更改代码。因此,要更改代码,您必须具有管理员访问权限,如果您这样做了,那么您无论如何都可以访问所有内容。:-)
客户端程序也是如此。如果唯一的安全是密码检查,你不需要绕过密码检查,你可以直接读取数据文件。
在这两种情况下,为了防止有权访问文件的人读取这些文件,密码检查是不够的。您必须加密数据。
现在让我们从基础开始,好吗?在进行登录凭证密码加密时,我们应该始终进行单向加密。一种加密方式意味着,一旦加密,您就无法解密文本。有一种称为加密md5
的方法,它只是一种加密方式。
Python 中已经有一个可用的库,名为hashlib
.
来自 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
更多信息:http ://docs.python.org/2/library/hashlib.html?highlight=hashlib#hashlib
要保护存储在客户端计算机上的数据,您必须对其进行加密。时期。
如果您信任授权用户,则可以使用基于密码的加密密钥(Stack Exchange 上的许多其他答案都解决了这个问题),并希望他足够聪明以保护他的计算机免受恶意软件的侵害。
如果您不信任授权用户(又名 DRM),那您就完全不走运了——找另一个项目。;-)
一种方法是以任何算法的散列形式存储密码,并检查给定密码的散列是否等于存储的密码散列。
第二种方法可能是获取像“cat”这样的密码并将它们转换为ascii,然后将它们相加并存储总和。然后,您可以将给定密码的 ascii 总和与您存储的密码进行比较。
或者你可以将它们结合起来!也许还散列 ascii 总和并比较给定密码的 ascii sun 散列。
这是我至少知道的三种方式。并且您可以在 python 中使用 chr 或 ord 默认函数来反复转换为 ascii。并且可以使用 hashlib 进行散列。
在过去的几天里,我一直在完善它并通过密码破解程序运行它,它似乎保持得相当强大。
这是我的代码供您查看:
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()
只要您根据需要进行调整,这几乎可以完成所有工作!