用于代码签名、GitHub 和电子邮件的多种 PGP 密钥实践

信息安全 密钥管理 pgp 打开pgp
2021-08-23 04:03:50

我有一套 PGP 证书使用的目标,并制定了我认为合理的计划作为解决方案。我想知道的是:

我是否忽略了需要或强烈建议更改我的解决方案的重要内容?

这个问题没有解决建议的密钥集合的维护,或生成、备份等的“最佳实践”。我在这里感兴趣的是我为自己设置的陷阱,或者我设置的安全漏洞创建,即评估计划本身。

介绍

我已经阅读了许多关于使用 PGP 密钥和子密钥的资料,其中大部分我现在无法指出,因为这是一个长期的研究问题,并且希望找到具体的答案,我没有保存我的踪迹。关于使用单个主键的多个子键用于各种目的而不是使用多个单一用途的专用主键,各方都有意见。我记得的两个相反的观点来自Alex CabalAlan Eliasen(一场我还没有评估过自己的辩论。)

作为第二个相互关联的问题,由于缺乏可以处理它们的野外实现,关于椭圆曲线键的使用及其“有用性”似乎存在一些争论(尽管都相当过时)。

威胁

不存在已知的异常威胁。国家/资金充足的参与者没有针对企业或我个人。没有可能针对业务或其代码库的非凡业务竞争。当然,随机黑客、脚本小子等的正常威胁总是存在的。寻求的主要保护是代码来源以及数据完整性和验证。一个次要目标是通过示例促进 PGP 的采用,并鼓励更多的人和企业开始将 PGP 用作规则而不是例外。我认为,将感知使用保持为简单有助于进一步实现该目标,并将 PGP 证书上的可见子密钥数量保持在最低限度似乎会增加“易于使用”的感知。

目标

我想建立一个系统或 PGP 证书集合,以支持以下目标:

  • 用于以我的业务名义签署对 GitHub 的提交的 PGP 密钥(代码出处)
  • 用于 SSH 访问 GitHub 上企业帐户的 PGP 密钥(安全性和便利性)
  • 企业在 GitHub 上或之外签署软件版本和分发的 PGP 密钥(代码完整性)
  • 用于业务的 PGP 密钥作为数字身份 - 电子邮件等 - 主要用于加密和签名
  • 在代码创建、代码分发和“作为一个实体的业务”之间创建关注点分离,以便密钥可用于:
    • 签署对其他存储库的提交
    • SSH 访问其他帐户、GitHub 或其他
    • 标志分发不是 100% 内部采购的
    • 对与代码完全无关的文档进行数字签名
    • 为企业创建数字身份,作为不与代码、GitHub 或其软件绑定的实体
  • 在不影响其他密钥的情况下“退休”或替换上述任何密钥的能力
  • 应用一组类似的 PGP 密钥,其中身份是​​我的个人而不是企业。

此外,我更喜欢尽可能接近完全地使用椭圆曲线(Curve25519/Ed25519)。当然,有可能在某些情况下我必须使用 RSA,并且一种优雅地“回退”到 RSA 的方法似乎是可取的。然而,我希望我使用 PGP 密钥的所有活动都能够处理椭圆曲线,并且永远不需要 RSA 功能。

计划

为了实现这些目标,我制定了一对平行计划。一个用于“身份”,另一个用于提供“后备”选项。

证书作业

对于身份计划,最初,我认为一些不同的 PGP 证书是可行的,并且符合上面给出的划分:

  • 企业作为一个实体的证书,具有认证、签名、认证和加密的能力。
    • 所有 UID 仅用于企业,与我或任何其他员工无关
    • 没有任何子密钥用于签署软件、git 提交、分发或其他
    • 没有任何子密钥用于在 GitHub 或其他代码存储库上进行身份验证
  • 专门用于签署企业发布的软件的证书
    • 签名旨在表明该业务是该包的分发点
    • 签名还允许验证该包的完整性
    • 软件的原始来源可能不是“签名”的一部分
    • 使用什么渠道进行分发无关紧要
    • 无论是源代码还是二进制 blob 也无关紧要
    • 证书没有可用的 auth 或 encrypt 使用的子密钥
    • 此证书由上述商业身份证书认证
  • 用于 GitHub 的第三个证书
    • 证书没有加密使用子密钥
    • auth 和 sign 使用在两个单独的子项中
    • auth 子键仅用于访问业务的 GitHub 账号
    • 将来对其他存储库的任何访问都将使用不同的新子项
    • 签名子密钥仅用于签署 git 提交和合并,而不是在 GitHub 上发布
    • 此证书由企业身份和上述代码签名证书认证
    • 进行提交的新员工需要一个证书,除 UID 外,其他所有方面都与此证书相同。
  • 能够代表企业行事的员工可以制作单独的证书
    • 从功能上讲,这与第一个证书相同,UID 将它们标识为业务的一部分,而不是业务本身(按名称或头衔 - 例如“销售”或“首席财务官”
    • 该证书将由企业身份证书认证。

虽然可能有点极端,但我认为以我自己的名义对上述前三个证书进行类似划分,供个人使用是可行的,并且有用的。在软件过程中涉及其他员工之前,我的个人证书似乎可以证明具有相同目的的商业证书是合理的。目前,如果企业签署分发或发布,是“我”在企业的授权下进行签署。拥有我的个人代码签名证书作为证明业务的证书有助于建立这种联系。如果其他人成为责任方,则无论如何都需要更换证书(两个人共享的私钥不再是“私人”)。在这种情况下,他们可以使用一些个人证书来证明新的业务代码签名密钥。

这种证书安排似乎明确了密钥的目的和企业身份之间的联系。它还提供了可供选择的选项,以适应每天都在发生合并、拆分、收购和解散的商业世界的现实。

证书要求

我制定的计划的后半部分,在需要时以及如果需要时,可以优雅地“回退”到 RSA,并为每个 PGP 证书制作了以下准则:

  • 主密钥将是 ECC 密钥 (Ed25519)
  • 主密钥将仅[C]启用,不[S],,[A][E]使用
  • 第一个子项(自动生成)将:
    • 使用与主 ECC 相同的密钥类型 (Curve25519/Ed25519)
    • 是单一用途的:[S],[A][E], 永远不要,[SA]即使允许
    • 选择的目的取决于密钥的用例是什么
      • [A] 用于主要用于 SSH 或类似用途的证书
      • [S] 对于主要用于提供数字签名的证书
      • [E] 对于主要用于个人的通用用途的证书,(最有可能用于电子邮件和其他通信,我更愿意在可能的情况下鼓励加密)
      • [S] 对于需要“签名”事物和通信的商业实体的通用证书,可能超过加密通信的需要。
    • 一制作就设置为过期
  • 其他子键(总是至少有一组)是:
    • 单一用途:[S],[A][E],[SA]即使允许
    • 与主密钥相同的密钥类型,ECC (Curve25519/Ed25519)
    • 设置有效期为 6-12 个月(取决于使用和暴露等)
    • 制作一个额外的子密钥,具有相同的用法和相反的密钥类型 RSA-4096
    • 附加子键一经制作就设置为过期

作为“回退”功能的额外层,上面制作的每个证书都由一个额外的证书补充,具有相同的子密钥集、用途和到期时间。区别在于:1)第一个具有 ECC 子密钥,第二个具有 RSA 子密钥,2)ECC 子密钥设置为过期而不是 RSA 子密钥,3)证书本身也设置为过期(使未过期的 RSA 子密钥无论如何都无法使用)。为了帮助使“回退”变得优雅,两个密钥都证明了另一个,我用来证明 ECC 版本的任何证书也将证明 RSA 版本。此外,每当我使用 ECC 证书来证明连接的证书时,例如上面的代码签名证书,我也使用 RSA 双证书来证明相同的证书。(因此,每个“认证”

讨论

使任何给定用途的一个子键都过期,这会迫使客户端程序“选择”一个可用的键,无论它是否是该用途的最新键。如果我遇到必须使用 RSA 的情况,我可以使相关子密钥过期而不会丢失以前制作的签名等。如果我被迫切换到 RSA 主密钥(在我看来不太可能),我也有一个可用的,它由已经在使用的 ECC 密钥(它是双胞胎)进行反认证。

如果不知何故,正在使用的子密钥的密钥被泄露,我仍然将最初创建的子密钥作为最后的手段。我可以撤销受损的子密钥并检索原始子密钥并继续操作。该子密钥未在我的密钥环上导入,甚至导出到密钥服务器,并以与主密钥本身相同的安全性离线存储。我相信,更好的做法是撤销被泄露的密钥,并在相同的主密钥下发布一个具有相同用途和类型的新子密钥。

从日常使用的角度来看,活动密钥环仅具有来自 ECC 主密钥的用于证书目的的子密钥(ECC 和 RSA 子密钥)。主密钥本身、自动创建的第一个子密钥和完整的 RSA 双主密钥集保留在备份媒体上。

作为演示,并且为了明确计划的实际效果,我生成了一组 PGP 证书。然后我使用 GnuPG 从不同的角度列出密钥和签名。首先是密钥生成系统,它知道所有内容,称为“as-generated”。其次是如何将它们导入我的密钥环,仅限 ECC 证书和有限的子密钥,称为“in-keyring”。第三是公开的内容可从密钥服务器获得,称为“密钥服务器”。所有六个(带和不带签名的三个视图)列表都已发布在Gist中,以便在必要时可以查看它们以“了解我的意思”。(我想将它们包括在这里,但似乎很长时间才能包含在问题中。

问题

所以,这堵文字墙支持了一个问题:

我是否忽略了一些重要的事情,需要或强烈建议改变我的解决方案,是否应该以更好的方式完成?

1个回答

我无法谈论椭圆曲线与 RSA 的问题或您打算如何处理它,但我建议您重新考虑您打算创建的密钥及其用途。

听起来您打算为特定目的创建密钥,但我建议 PGP 密钥意味着代表身份。这可能意味着公司、个人、为公司工作的人(与个人)等。密钥由其他密钥签名,以建立“我已验证(合理)怀疑此身份控制此 PGP 密钥。” 如果我们从未验证过某个特定的密钥是否属于某人(我信任 Bob,Bob 签署了 Alice 的密钥,我可以相信 Alice 控制该密钥,就像我信任 Bob 一样多。)单独的(主)键:

  • 用于以我的企业名义签署对 GitHub 的提交的 PGP 密钥
  • 用于 SSH 访问 GitHub 上企业帐户的 PGP 密钥
  • 用于企业在 GitHub 上或之外签署软件版本和分发的 PGP 密钥
  • 用于业务的 PGP 密钥作为数字身份 - 电子邮件等 - 主要用于加密和签名
  • 在代码创建、代码分发和“作为一个实体的业务”之间创建关注点分离

似乎过于复杂,并且有点与将密钥作为证明身份的想法背道而驰。可以满足您既定目标的替代方案可能类似于

  • 代表公司的钥匙

    • 签署代码发布和/或员工密钥的签名密钥
    • 身份验证密钥(misc/admin SSH 访问)
  • 每个员工的钥匙

    • 提交/代码发布、电子邮件的签名密钥
    • 电子邮件等的加密密钥
    • 身份验证密钥(更精细地授予对 GitHub 等所有帐户的访问权限)

这允许您限制对必要最低权限的访问(销售人员可能需要密钥来签署他们的电子邮件,他们不需要访问 GitHub 存储库)确定谁执行了特定操作,例如签署对公司 git 存储库的提交。

为了简化入职(实施新密钥),您可以使用公司密钥签署员工密钥,并确定任何信任公司密钥的人都可以相信此人的密钥是真正创建用于签署他们的业务电子邮件/git 提交等。它也是可以在员工离开公司时“取消签名”密钥,从而减少密钥管理的麻烦(取消签名一个密钥比撤销/重新创建/重新分发主 SSH/签名密钥更容易)。

还值得一提的是,让一个或多个员工密钥签署代码发布,而不是拥有一个需要访问才能发布的主密钥,这似乎是一种公认​​的做法(至少对于制作我使用的 PGP 软件的人来说)。

将所有员工钥匙的副本保存在托管中也是明智的,以防他们以不良条件离开公司/被公共汽车撞到。有很多关于安全堆栈交换的答案讨论了实现这一点的正确方法。

希望对您有所帮助,如果我浪费了您的时间,请见谅。

编辑:链接到另一个与管理需要在员工之间“共享”的组织身份相关的问题。