Emacs 中配置 .authinfo.gpg
文章介绍如何在Emacs中安全存储API密钥,通过GnuPG加密~/.authinfo文件,并配置Emacs读取加密后的文件。还介绍了EasyPG Assistant和pass工具的使用方法。 2025-2-26 16:0:0 Author: taxodium.ink(查看原文) 阅读量:17 收藏

之前我写过一篇在 Emacs 中集成翻译插件的文章,插件依赖一些 LLM 服务,LLM 服务需要配置对应的 API key,它们是定义在 ~/.authinfo 中的。

但是 ~/.authinfo 是未加密的,如果泄露了,那么我的 API key 就会泄露被滥用,所以我觉得还是需要对它做一层加密。

这篇文章我会分享如何在 ~/.authinfo 中定义 API key、如何使用 GnuPG 对 ~/.authinfo 加密,以及如何配置 Emacs 从加密后的 ~/.authinfo.gpg 中读取 API key。

authinfo

有些连接到其他服务的 Emacs 软件包需要身份验证,由于反复提供相同的用户名和密码可能会令人烦恼,Emacs 通过 auth-source 库提供了持久化信息。

默认情况下,身份验证信息来自 ~/.authinfo~/.authinfo.gpg~/.netrc 文件。

这些文件的语法与 ftp 程序中的 netrc 文件类似,如下所示:

machine mymachine login myloginname password mypassword port myport

Source

Emacs 是通过 auth-source 去实现身份验证的,一般将验证信息(例如 API Key)存储在这三个文件中:

  • ~/.authinfo
  • ~/.authinfo.gpg (加密)
  • ~/.netrc

而验证信息的格式是:

machine mymachine login myloginname password mypassword port myport

其中:

  • machine 服务器,DNS 名称或 IP 地址,在 auth-source-search1 查询中称为 :host
  • login 是用户名,在 auth-source-search 查询中称为 :user 。也可以使用 login 和 account 。
  • port 是连接端口或协议,在 auth-source-search 查询中称为 :port
  • password 就是对应的密钥,或者 API key 之类的

一些例子:

machine localhost login spike port sudo password xxxx
machine 192.168.100.100 login root port ssh password xxxx
machine api.deepseek.com login apikey password xxxx
machine api.siliconflow.cn login apikey password xxxx
machine openrouter.ai login apikey password xxxx
machine openrouter.ai/api login apikey password xxxx

一些插件可能会基于 machine 或者 login 去查找密钥,具体如何设置就需要看插件是如何读取的。

例如 emacs-immersive-translate 是这样读取的:

immersive-translate-api-key:

(defun immersive-translate-api-key (host user)
  "Lookup api key in the auth source.

By default, `immersive-translate-chatgpt-host' is used as HOST
and \"apikey\" as USER in Chatgpt backend.
\"fanyi-api.baidu.com\" is used as HOST and
`immersive-translate-baidu-appid' as USER in Baidu backend."
  (if-let ((secret (plist-get (car (auth-source-search
                                    :host host
                                    :user user
                                    :require '(:secret)))
                              :secret)))
      (if (functionp secret)
          (encode-coding-string (funcall secret) 'utf-8)
        secret)
    (user-error "No %s found in the auth source" user)))

immersive-translate-chatgpt.el 中设置 ChatGPT 的密钥:

;; ...其他代码
("Authorization" . ,(concat "Bearer " (immersive-translate-api-key
                                       immersive-translate-chatgpt-host
                                       "apikey"))))))
;; ...其他代码

可以看到,emacs-immersive-translate 基于 :host 和 :user 去查找的:

  • :host (machine) 是 immersive-translate-chatgpt-host ,默认是 api.openai.com
  • :user (login) 是 apikey

所以按照默认配置,当你获取到 openai 的 API key 后,要这样配置:

machine api.openai.com login apikey password your_openai_api_key

GnuPG 加密

我对 GnuPG 研究得不多,简单分享一下如何创建 gpg 密钥,如何加密文件。

  1. 创建 gpg 密钥

执行 gpg --full-generate-key ,按照提示完成创建即可。

创建完成后可以通过 gpg --list-keys 查看当前得密钥,例如我执行后会得到:

/home/spike/.gnupg/pubring.kbx
------------------------------
pub   rsa4096 2025-02-27 [SC]
      1BAF5568B6AFD3DB367B865B50AC4C6F1FD4B1CF
uid           [ultimate] SpikeLeung <[email protected]>
sub   rsa4096 2025-02-27 [E]

其中:

  • 1BAF5568B6AFD3DB367B865B50AC4C6F1FD4B1CF 是指纹(fingerprint)2
  • [ultimate] SpikeLeung <[email protected]> 是 uid
  • [email protected] 是和这个 gpg 密钥关联的邮箱
  • 加密文件

gpg -e -r "SpikeLeung" ~/.authinfo 或者 gpg -e -r "[email protected]" ~/.authinfo

其中, -e 表示加密, -r 指定使用哪个 user-id,对应的是上面 uid 中的内容,你可以用名字或者邮箱。

加密成功的话,就会在当前目录生成一个带有 .gpg 后缀的加密文件 ~/.authinfo.gpg

配置 Emacs 读取 ~/.authinfo.gpg

原来 ~/.authinfo 是未加密的,Emacs 里可以随便访问,现在加密了,那么在访问前就要先解密才能访问了。

为了让 Emacs 能够解密 gpg 加密的文件,我们需要让 Emacs 能够读取 gpg 密钥,然后用密钥去解密。

EasyPG Assistant (epa-file)

EasyPG Assistant3 是 Emacs 内置的包,当需要访问 gpg 加密文件的时候就会启用。

我是在终端中使用 Emacs 的,默认输入密码是弹窗输入,输入的时候很容易卡顿,可以添加下面的配置:

(setq epa-pinentry-mode 'loopback) ;; 在 minibuffer 输入密码

这样 Emacs 会从 minibuffer 读取密码,更流畅。

The Unix password store (pass)

除了 EasyPG Assistant,你也可以用 The Unix password store (pass),这是一个简单的密码管理程序。

EasyPG Assistant 主要是和 Emacs 集成,方便打开和保存文件。

pass 是更侧重于密码管理,Emacs 也可以和 pass 集成。

如果你的环境中没有 pass,首先你需要按照文档安装好。

然后初始化 pass: pass init gpg-id ,这里的 gpg-id 可以是:

  • fingerprint: 1BAF5568B6AFD3DB367B865B50AC4C6F1FD4B1CF
  • uid: SpikeLeung 或者 [email protected]

这样,pass 就配置好了。

接下来就是告诉 Emacs 启用 pass,在配置文件中添加一下配置即可:

(auth-source-pass-enable)

写在最后

我对 GnuPG 其实不太熟悉,文章中如果有什么错误,欢迎留言指正~

Date: 2025-02-27 Thu 00:00

Last Modified: 2025-02-27 Thu 22:50

License: CC BY-NC 4.0


文章来源: https://taxodium.ink/config-authinfo-with-emacs.html
如有侵权请联系:admin#unsafe.sh