使用这个 Python 模块输入不可见的密码

使用 GPG 和 Python getpass 模块为您的密码增加额外的安全层。
56 位读者喜欢这个。
Password

freeGraphicToday,通过 Pixabay。 CC0。

密码对于程序员来说尤其麻烦。你不应该在不加密的情况下存储它们,而且你不应该在你用户输入密码时泄露输入的内容。当我决定要提高我的笔记本电脑的安全性时,这一点对我来说变得尤为重要。我加密了我的主目录——但是一旦我登录,任何以明文形式存储在配置文件中的密码都可能暴露在窥探之下。

具体来说,我使用名为 Mutt 的应用程序作为我的电子邮件客户端。它让我在 Linux 终端中阅读和撰写电子邮件,但通常它期望在配置文件中有一个密码。我限制了我的 Mutt 配置文件的权限,以便只有我才能看到它,但我是我笔记本电脑的唯一用户,所以我并不真正担心经过身份验证的用户不小心查看我的配置。相反,我想要保护自己免于心不在焉地将我的配置发布到网上,无论是为了炫耀还是版本控制,从而暴露我的密码。此外,尽管我不期望我的系统上有不受欢迎的访客,但我确实想确保入侵者无法仅通过在我的配置上运行 cat 来获取我的密码。

Python GnuPG

Python 模块 python-gnupggpg 应用程序的 Python 封装器。该模块的名称是 python-gnupg,您一定不要将其与名为 gnupg 的模块混淆。

GnuPG (GPG)是 Linux 的默认加密系统,我从 2009 年左右开始使用它。我对它感到放心,并且对其安全性有很高的信任度。

我决定将密码输入 Mutt 的最佳方法是将我的密码存储在加密的 GPG 文件中,创建一个提示符来输入我的 GPG 密码以解锁加密文件,并将密码交给 Mutt(实际上是交给 offlineimap 命令,我使用它来同步我的笔记本电脑和电子邮件服务器)。

使用 Python 获取用户输入 非常容易。您调用 input,用户输入的任何内容都将存储为一个变量

print("Enter password: ")
myinput = input()

print("You entered: ", myinput)

我的问题是,当我在终端中输入密码以响应我的密码提示时,我输入的所有内容对于任何从我肩膀上方看或滚动浏览我的终端历史记录的人来说都是可见的

$ ./test.py
Enter password: my-Complex-Passphrase

使用 getpass 进行不可见的密码输入

通常情况下,已经有一个 Python 模块解决了我的问题。该模块是 getpass4,从用户的角度来看,它的行为与 input 完全相同,只是不显示用户正在输入的内容。

您可以使用 pip 安装这两个模块

$ python -m pip install --user \
python-gnupg getpass4

这是我的 Python 脚本,用于创建密码提示

#!/usr/bin/env python
# by Seth Kenlon
# GPLv3

# install deps:
# python3 -m pip install --user python-gnupg getpass4

import gnupg
import getpass
from pathlib import Path

def get_api_pass():
    homedir = str(Path.home())
    gpg = gnupg.GPG(gnupghome=os.path.join(homedir,".gnupg"), use_agent=True)
    passwd = getpass.getpass(prompt="Enter your GnuPG password: ", stream=None)

    with open(os.path.join(homedir,'.mutt','pass.gpg'), 'rb') as f:
        apipass = (gpg.decrypt_file(f, passphrase=passwd))

    f.close()

    return str(apipass)
    
if __name__ == "__main__":
    apipass = get_api_pass()
    print(apipass)

如果您想试用,请将文件另存为 password_prompt.py。如果您正在使用 offlineimap 并且想将此解决方案用于您自己的密码输入,则将其保存到您可以让 offlineimap 在您的 .offlineimaprc 文件中指向的某个位置(我使用 ~/.mutt/password_prompt.py)。

测试密码提示

要查看脚本的运行情况,您首先必须创建一个加密文件(我假设您已经设置了 GPG)

$ echo "hello world" > pass
$ gpg --encrypt pass
$ mv pass.gpg ~/.mutt/pass.gpg
$ rm pass

现在运行 Python 脚本

$ python ~/.mutt/password_prompt.py
Enter your GPG password:
hello world

当您输入时,没有任何显示,但只要您正确输入您的 GPG 密码,您就会看到测试消息。

将密码提示与 offlineimap 集成

我需要将我的新提示与 offlineimap 命令集成。我选择 Python 来编写这个脚本是因为我知道 offlineimap 可以调用 Python 应用程序。如果您是 offlineimap 用户,您会欣赏所需的唯一“集成”是更改您的 .offlineimaprc 文件中的两行。

首先,添加一行引用 Python 文件

pythonfile = ~/.mutt/password_prompt.py

然后将 .offlineimaprc 中的 remotepasseval 行替换为对 password_prompt.pyget_api_pass() 函数的调用

remotepasseval = get_api_pass()

配置文件中不再有密码!

安全至关重要

有时,考虑个人计算机上的安全细节感觉几乎是偏执的。您的 SSH 配置真的需要限制为 600 吗?您的电子邮件密码位于隐藏文件夹 .mutt 内的一个无关紧要的配置文件中真的重要吗?可能不是。

然而,知道我没有将敏感数据悄悄地隐藏在我的配置文件中,这让我更容易将文件提交到公共 Git 仓库,将代码片段复制并粘贴到支持论坛中,并以实际的、已知良好的配置文件的形式分享我的知识。仅凭这一点,改进的安全性就让我的生活变得更轻松。并且凭借如此多可用的优秀 Python 模块,它很容易实现。

接下来阅读什么
Seth Kenlon
Seth Kenlon 是一位 UNIX 极客、自由文化倡导者、独立多媒体艺术家和 D&D 爱好者。他曾在电影和计算机行业工作,通常同时进行。

评论已关闭。

知识共享许可协议本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.