ChatGPT解决这个技术问题 Extra ChatGPT

获取隐藏密码输入

您知道在 Linux 中,当您尝试一些 Sudo 内容时,它会告诉您输入密码,并且当您键入时,终端窗口中没有显示任何内容(未显示密码)?

有没有办法在 Python 中做到这一点?我正在编写一个需要如此敏感信息的脚本,并希望在我输入时将其隐藏。

换句话说,我想在不显示密码的情况下从用户那里获取密码。


S
Sven Marnach

使用 getpass.getpass()

from getpass import getpass
password = getpass()

可选提示可以作为参数传递;默认值为 "Password: "

请注意,此功能需要正确的终端,因此它可以关闭输入字符的回显 - 请参阅 “GetPassWarning: Can not control echo on the terminal” when running from IDLE 了解更多详细信息。


会起作用,但是如何小心“黑客”,他会复制脚本然后注释掉需要用户密码的行?
@asf107:如果黑客可以编辑源代码,还有其他问题需要担心。
@asf107 - 请求密码背后的想法是,您可以将其传递给某些东西进行身份验证(IE,我正在使用它来请求密码以通过在线服务器进行身份验证)。如果黑客注释掉了该行,程序就会失败,因为服务器将不再被验证。使用 getpass() 背后的想法是,没有人可以通过阅读源代码来找到您的密码,并且没有人可以通过盯着您的肩膀并在您键入密码时从屏幕上读出您的密码来获取您的密码在。
C
Cœur
import getpass

pswd = getpass.getpass('Password:')

getpass 适用于 Linux、Windows 和 Mac。


“密码:”(冒号后有一个空格)是默认提示,因此通常不需要在调用 getpass.getpass() 时指定它。
getpass 是一个至少从 Python 2.5 开始就存在的标准库模块
这在 IDLE 中给了我一个错误 Warning (from warnings module): File "C:\Python27\lib\getpass.py", line 92 return fallback_getpass(prompt, stream) GetPassWarning: Can not control echo on the terminal. Warning: Password input may be echoed. ,但在命令提示符下运行良好,找到原因 here
getpass() 不适用于 IDLE。没有getpass()还有另一种方法可以实现吗?
要在 stderr 上显示提示(您还需要 import sys):getpass.getpass(<string>,sys.stderr)
R
RanRag

为此目的使用 getpass

getpass.getpass - 提示用户输入密码而不回显


回显 * 字符怎么样?
w
wjandrea

此代码将打印一个星号而不是每个字母。

import sys
import msvcrt

passwor = ''
while True:
    x = msvcrt.getch()
    if x == '\r':
        break
    sys.stdout.write('*')
    passwor +=x

print '\n'+passwor

这只是 Windows,但至少它没有重复 getpass 答案。好的
不会处理退格键。
我不确定您的代码是否适用于 Python 2.x,但这对我不起作用。我正在运行 Python 3.x。我得到的第一个错误是 'passwor += x' 行的 TypeError。它说:“无法将字节对象隐式转换为 str”。我更改了这一行,以便将 x 显式转换为字符串,例如:“password += str(x)”。但是代码仍然不起作用。当我运行它时,它不会提示我输入,它只会永远打印星号。
@Larper 适用于 Python 2,请参见代码的最后一行
@MilkyWay90 需要对该代码进行一些修改才能与 Python 3 兼容。已提交修改后的代码编辑。希望它得到批准:)
M
Mostafa Hassan

更新@Ahmed ALaa 的答案

# import msvcrt
import getch

def getPass():
    passwor = ''
    while True:
        x = getch.getch()
        # x = msvcrt.getch().decode("utf-8")
        if x == '\r' or x == '\n':
            break
        print('*', end='', flush=True)
        passwor +=x
    return passwor

print("\nout=", getPass())

msvcrt us 仅适用于 Windows,但 PyPI 中的 getch 应该适用于两者(我只用 linux 测试过)。您还可以注释/取消注释这两行以使其适用于 Windows。


不要这样做......人们已经这样做了...... stackoverflow.com/a/67327327/701532
S
Sagar

这是我基于@Ahmed ALaa 提供的代码的代码

特征:

适用于最多 64 个字符的密码

接受退格输入

输出 * 字符 (DEC: 42 ; HEX: 0x2A) 而不是输入字符

缺点:

仅适用于 Windows

函数 secure_password_input() 在调用时将密码作为 string 返回。它接受 Password Prompt 字符串,该字符串将显示给用户以输入密码

def secure_password_input(prompt=''):
    p_s = ''
    proxy_string = [' '] * 64
    while True:
        sys.stdout.write('\x0D' + prompt + ''.join(proxy_string))
        c = msvcrt.getch()
        if c == b'\r':
            break
        elif c == b'\x08':
            p_s = p_s[:-1]
            proxy_string[len(p_s)] = " "
        else:
            proxy_string[len(p_s)] = "*"
            p_s += c.decode()

    sys.stdout.write('\n')
    return p_s

不要这样做......人们已经这样做了...... stackoverflow.com/a/67327327/701532
@anthony 我发现用标准导入编写一个 16 行函数更明智。此外,我可以看到引擎盖下运行的内容,并且可以根据需要自定义内容
是的,为自己定制……但是其他用户呢?同样从个人经验来看,即使是处理星星也会很快变得复杂,处理控制字符、unicode、杀行,甚至是简单的……关闭回显(输入开始时的退格选项卡)。更好的理由是专注于使用“密码助手”的能力,例如已经提供“星号密码输入”的“系统询问密码”。 SSH 和 SUDO 都可以做到这一点!然后,用户可以选择自己的密码输入方式,可以是星号,也可以是密码管理器或其他来源!