如何使用私钥在GPG中加密文件

11

我正在为一些系统制作更新,希望通过加密来保持机密性、完整性和签名的有效性。我想用我的私钥加密文件并将其发送给客户,以便他们可以使用我的公钥进行解密。但GPG的工作方式是使用公钥加密和私钥解密。我不想发送我的私钥,以便我可以更改它并向其他人发送公钥。有什么想法吗?


但是 GPG 的工作方式是使用公钥进行加密,使用私钥进行解密。这绝对不可能。因为这将需要发布您的私钥,这是绝对不会做的。您是从哪里得出这个结论的? - scai
1
这个问题似乎与编程或开发无关,因此不属于适当的主题。请参阅帮助中心中的我可以在这里提什么样的问题。也许超级用户信息安全堆栈交换会是更好的提问地点。另请参阅我应该在哪里发布有关Dev Ops的问题? - jww
5个回答

25

你的意思在gpg术语中不叫做"加密",而是叫做"签名"。

签名基本上是用你的私钥进行加密,然后用公钥进行解密。

使用:

 gpg --sign myfile.ext

或者使用您的电子邮件客户端的签名功能。

签名显然会让所有拥有您的“公钥”的人都能读取文件内容(由于“公钥”通常是公开的,这将允许每个人解密内容)。

如果您正在寻找一种只有收件人才能解密内容的方法,那么您需要以一种只有收件人可以访问解密令牌的方式加密数据。显然,收件人需要拥有这样的令牌(也就是说,您使用他们的公钥进行编码,因此他们可以使用自己的私钥进行解码)。

更新

简而言之:如果您想保证完整性(即:收件人确实知道数据来自而不是其他人),则需要签名数据。 如果您想保证机密性(即:只有您的收件人可以阅读数据),则需要加密数据。

无论是签名还是加密,它们其实都是同一件事情。 唯一的区别在于,谁可以访问密钥。

使用签名时,您使用私钥加密数据,可以使用公钥解密(由于每个人都可以访问公钥,因此每个人都可以解密它,从而每个人都可以验证数据已由签名)。

使用加密时,您使用收件人的公钥加密数据,他们使用自己的私钥解密它(所以只有他们能读取它;但是任何人都可以向他们发送加密的数据,他们无法保证它确实来自发件人,但可以确保只有他们能读取它)。

如果您需要机密性和完整性,需要同时进行签名和加密,并且为此,您和您的收件人都需要拥有(不同的)公钥/私钥对。

结论

由于签名和加密其实是相同的,只要您完全掌控涉及的密钥的可用性,就可以使用两者来保证数据的有效性和完整性。


2
这正是我所需要的,但您确定在这种情况下签名可以保持内容的机密性,只要公钥不可用? - Hamid Reza Moradi
2
我测试了这个方法。它不保持机密性,只是签署包裹。数据将以明文形式在机器之间传输。还有其他方法吗? 我创建了一个带有一些文本的文件,并使用gpg --sing text.txt进行签名。 然后我vi text.txt.gpg,发现我的文本清晰可见。 - Hamid Reza Moradi
2
看下面这个例子: echo "这是一个测试"> test2.txt; gpg --sign test2.txt; cat test2.txt.gpg - Hamid Reza Moradi
4
我刚刚注意到我的 gpg(来自 Ubuntu 的 1.4.11 版)的“--sign”选项没有产生加密文档(这需要根据手册指定“--sign”和“--encrypt”以将其加密给特定收件人)。也就是说,你可以使用“--decrypt”读取明文,而无需拥有公钥,但是你无法检查签名是否正确。因此 @HamidRezaMoradi 是正确的,单个“--sign”不能用于在此处提供保密性(明文仅被压缩而不是加密)。 - scai
2
我刚独立完成了所有这些,并确认签名不会加密有效载荷。如果在您的--sign命令中添加“--compress-level 0”,那么很容易看到,因为这会禁用压缩,结果是您的明文仅包裹在签名中。 - Peter Hansen
显示剩余6条评论

9
GnuPG并不要求你公开你的私钥以加密文档,这是错误的想法。你应该绝对不会向任何人公开你的私钥。GnuPG支持两种不同的加密方法:非对称加密和对称加密。
使用非对称加密需要知道接收方的公钥,通常情况下这不是问题,因为公钥不是秘密而是众所周知的。为了再次解密,只能使用接收方知道的私钥。使用GnuPG进行非对称加密可以使用--encrypt选项进行。
如果你不知道接收方的公钥,那么可以使用对称加密,这里双方共享相同的密钥。当然,这需要一个安全的信道来传输共享密钥。对于对称加密,请使用--symmetric选项。这里不需要公钥或私钥,但是共享密钥的安全交换使得对称加密容易受到攻击。
如果你只需要保证完整性和可追溯性(检测到文档未经修改并且能够验证谁创建/签署的文档),则可以使用--sign选项使用私钥创建签名。所有可以访问你的公钥的人都可以检查此签名以验证完整性和可追溯性。但请注意,任何人都可以读取你的原始消息内容,因为这个签名不提供加密。生成的.gpg文件看起来像二进制数据,但只包含压缩但未加密的文本。你还可以通过指定--compress-level 0来禁用压缩,并查看输出文件中包含的明文原始消息内容。因此,如果您需要保密,请勿使用此选项。

2
我正在处理一个相似的问题:从中央源分发软件更新,以应用于许多现场终端用户。 终端用户需要验证更新来自官方来源(使用私钥签名),但我还希望更新能够保密传输(加密)。
在我大约30年前上大学时的密码学课程中,他们教授使用私钥进行加密与签署消息是同一件事情-当接收者使用公钥解密时,他们没有得到乱码就确认了使用了私钥进行加密。这也提供了某种程度的机密性,如果公钥被保密,则会是我的首选实现方式。
正如其他人所提到的,我已确认gpg --sign操作不会对消息进行加密,消息在签名文件中以明文形式可见。为了使用gpg实现同时具有通过私钥进行签名的确定真实性和合理的保密性,我决定给基于现场的接收器提供自己的密钥对,除了更新发布者的公钥之外。这并不是非常安全的解决方案,任何人都可以反向工程化现场设备并获得它将保存的"秘密"密钥,使用它们可以解密已签名的更新消息并查看其明文内容。但是他们无法创建具有分销商秘密密钥签名的文件,因此他们无法创建自己的更新,这些更新将被在寻找使用其公钥进行加密和更新分销商私有持有密钥签名的设备中接受。
这是一种暴露程度的问题。 在传输过程中,更新对没有访问端点设备进行反向工程化的任何人都是安全的。通过物理访问终端(我们无法防止),他们最终将能够反向工程化安装的软件,甚至是更新本身,但他们永远无法签署自己的更新并将其推送到未受影响的机器。 至少在RSA安全的情况下是如此。

0
简单的答案:忘掉“密钥”的概念。你只需要一个共享的秘密“密码”。所以和你的客户见面吧。用电话联系他们。或者如果你很多疑,可以面对面谈。达成一致并取得一个你们都知道的秘密密码,并且保持它足够的安全。根据我的经验,我推荐使用Diceware来选择共享的密码。你们两个都要保留安全的副本。如果你很多疑,不要写下来——记住它!现在你可以使用共享的密码来加密任何东西了。任何对称加密工具都可以为你做到这一点,包括GPG。

-5
可能需要为此明确目的准备一个单独的密钥对,并分发私钥,同时保持公钥保密(是的,就术语而言有点相反);然后您可以使用公钥正常加密更新,并且接收者可以使用私钥解密它们。

问题在于当您导出私钥时,公钥也会一同传输,而且您甚至不能删除公钥,除非您先删除其对应的私钥。 - Hamid Reza Moradi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接