我经常使用 GnuPG 使用密码来加密文件。我很偏执,担心 GnuPG 使用的密钥派生不够慢。
出于这个原因,我决定在将密码输入 GnuPG 之前进行自己的密钥派生。
我有一个 Python 脚本,它使用静态盐运行 1000 万轮 PBKDF2-SHA512,并输出十六进制编码的结果。我称之为“预推导”。
我首先在密码短语上运行它,并将其输出作为中间密码短语提供给 GnuPG。
我是在正确的轨道上,还是在浪费时间做这件事,或者更糟糕的是,削弱了加密安全性?
我经常使用 GnuPG 使用密码来加密文件。我很偏执,担心 GnuPG 使用的密钥派生不够慢。
出于这个原因,我决定在将密码输入 GnuPG 之前进行自己的密钥派生。
我有一个 Python 脚本,它使用静态盐运行 1000 万轮 PBKDF2-SHA512,并输出十六进制编码的结果。我称之为“预推导”。
我首先在密码短语上运行它,并将其输出作为中间密码短语提供给 GnuPG。
我是在正确的轨道上,还是在浪费时间做这件事,或者更糟糕的是,削弱了加密安全性?
除了您最好不要部署自定义加密代码这一事实之外,您正在重新发明轮子。OpenPGP 的字符串到键功能是可配置的,可以根据您的需要进行调整,同时不会失去兼容性。我不是在这里讨论你对周期数的选择,尽管它们看起来有点苛刻。我建议阅读在什么时候向 PBKDF2 添加更多迭代不会提供额外的安全性?关于这个话题。
来自man gpg:
--s2k-cipher-algo name使用名称与如果密码对称加密的加密算法
--personal-cipher-preferences,并--cipher-algo没有给出。默认值为 AES-128。
--s2k-digest-algo name使用名称作为用于破坏对称加密密码的摘要算法。默认值为 SHA-1。
--s2k-mode n选择如何修改对称加密的密码。如果 n 为 0,则将使用普通密码(通常不推荐),1 向密码添加盐(不应使用),3(默认)迭代整个过程多次(见
--s2k-count)。
--s2k-count n指定重复对称加密的密码短语修改的次数。此值的范围可能在 1024 和 65011712 之间(包括 1024 和 65011712)。默认值是从 gpg-agent 查询的。请注意,并非 1024-65011712 范围内的所有值都是合法的,如果选择了非法值,GnuPG 将四舍五入到最接近的合法值。
--s2k-mode此选项仅在设置为默认值 3时才有意义。
总而言之,以下选项将具有相同的效果:
gpg --s2k-mode 3 --s2k-digest-algo SHA512 --s2k-count 10000000 --symmetric
--s2k-mode 3是 GnuPG 的默认设置(也是此选项的唯一合理设置);我没有包括在内--s2k-cipher-algo,因为这与密钥推导无关(无论如何,您描述的“预推导”也没有处理)。或者,您可以将其设置为默认值gpg.conf:
s2k-mode 3
s2k-digest-algo SHA512
s2k-count 10000000
这些选项不仅可以用于消息/文件的对称加密,还可以用于私钥的密码保护。
虽然保护您的密码是维护 GPG 安全性的最关键部分,但您很可能正在削弱而不是加强现有的安全性。
尽量减少密码在计算机内存中的时间至关重要。我确信 GPG 会适当地将内存归零以最大程度地减少曝光。但是像 Python 这样的内存管理语言并不能真正促进安全的字符串操作。这意味着您的初始密码以及您传递给 GPG 的密码可能会留在您计算机的虚拟内存中(将其读取为磁盘上)。提取它的可能性有多大尚待商榷,但它肯定比 GPG 将你的钥匙留在身边的时间要长得多。
您也没有提到如何将 SHA512 哈希输入 GPG。如果您将其打印出来,甚至可能将其复制并粘贴到 GPG 中,那就太糟糕了。(复制缓冲区不应该用于秘密数据。)
因此,我建议您使用现有的 GPG 选项(请参阅@JenErat 的答案以获得出色的概述)并尽量记住您不应该推出自己的 crypto。