【问题标题】:Getting a hidden password input获取隐藏密码输入
【发布时间】:2012-03-01 09:55:50
【问题描述】:

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

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

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

【问题讨论】:

    标签: python passwords user-input


    【解决方案1】:

    使用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() 背后的想法是,没有人可以通过阅读源代码来查看您的密码,并且没有人可以通过盯着您的肩膀并在您输入密码时从屏幕上读出您的密码来获取您的密码在。
    【解决方案2】:
    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(,sys.stderr)
    【解决方案3】:

    为此使用getpass

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

    【讨论】:

    • 回显 * 字符怎么样?
    【解决方案4】:

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

    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 兼容。已提交修改后的代码编辑。希望它得到批准:)
    【解决方案5】:

    更新@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
    【解决方案6】:

    这是我基于 @Ahmed ALaa

    提供的代码的代码

    特点:

    • 适用于最多 64 个字符的密码
    • 接受退格输入
    • 输出 * 字符 (DEC: 42 ; HEX: 0x2A) 而不是输入字符

    缺点:

    • 仅适用于 Windows

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

    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 都可以做到这一点!然后,用户可以选择自己的密码输入方式,可以是星号、密码管理器或其他来源!
    猜你喜欢
    • 2013-08-19
    • 2011-12-06
    • 2012-06-14
    • 2012-04-25
    • 2021-07-03
    • 1970-01-01
    相关资源
    最近更新 更多