跳到主要内容

别把 MCP 密钥放进环境变量了

一键三连
一键三连

· 阅读约 2 分钟

这个动作你一周至少做两次:拉一个新的 MCP 进来,或者换一台机器,把私钥贴进 .env,然后告诉自己“文件权限看着呢,没事”。我每次贴完都有一点不安。环境变量挂在 /proc 里,有读权限的进程就能摸走,这我三年前就知道了,只是一直没动手。

没动手的原因说不上体面:网上搬密钥进硬件的教程各说各话,有的让先装驱动卡,有的让重新烧卡槽,看着比再配一把密钥还累,我就继续贴环境变量,贴一次别扭一次。

上周读到一篇 arXiv 上的论文,数字有点吓人:同样的 12 个注入场景、192 个样本,裸测攻击成功率 19.3%,把私钥锁进硬件之后,0%,95% 置信区间上界 2.0%。论文还记了一个生产事故,私钥被一个广泛部署的框架用邮件注入不到五分钟就抄走了。我那天下午就把常用的那把 MCP 签名密钥从 .env 挪进了硬件。

方案本身不新鲜,PKCS#11——密钥待在智能卡或者 TPM 里,签名操作在硬件里算,进程只拿到一个不透明句柄去调用结果,想要密钥原文?拿不到!论文管这叫零信任硬件执行边界,五层栈里我只关心最后一层,前四层没细看。

搬的话,如果你手头有张吃灰的 smartcard,或者机器自带 TPM,直接把旧钥匙忘了,生成一把新的就行!

pkcs11-tool --keypairgen --key-type EC:secp256r1 --label mcp-signing-key --login --pin 123456

我一开始还折腾怎么把旧钥匙迁进去,搞了半天才意识到直接生成新的就行——生成这一步在硬件里完成,密钥材料从头到尾没碰过文件系统,也就不存在“导出”这回事。然后让 MCP 客户端走 PKCS#11 接口,配置大概长这样:

provider = "pkcs11"
label = "mcp-signing-key"

token 名各家槽位不一样,我没法给一个通用值,看你自己客户端认哪个。PIN 每次现输,或者交给系统钥匙串,反正不放 .env,不然就白搬了。⚡这一下,私钥不再存在于任何路径里,进程想读也读不到,只能拿到句柄去调结果。以前每次想起钥匙在那躺着都有的那点别扭,没了。

生成密钥加改配置,半小时,其中二十五分钟耗在“旧钥匙到底要不要迁”这个假问题上。这周用下来的体感,省下的不是时间,是持续了三年的那种惦记——上回绑键位是三分钟回本,这一单是三年回本。老实说这招不万能,如果你的 MCP 大多跑在云上没有本地硬件可挂,那就得先架远程签名服务,不是一条命令的事。但本地开发这一摊,回不去了。

更多「MCP」的实战

评论(1)

复现不了复现不了

我的 pkcs11-tool 是 0.24 的,命令能跑通,但客户端配置里 label 就是找不到,是不是版本问题?步骤都一样啊😢