Bitbucket:如何在不为这台笔记本电脑设置 ssh 密钥的情况下从笔记本电脑推送到 repo?

Bitbucket: How am I able to push to a repo from a laptop without setting the ssh key for this laptop?

我真的很困惑我的 bitbucket 的行为:

  1. 我有一个项目叫Prototype,下面有多个仓库;

  2. 我能够将新提交推送到名为 Tiger 的存储库;而且我假设我已经在 bitbucket 的“个人 Settings/SSH 密钥”中设置了笔记本电脑的 ssh 密钥,因为如果我没有这样做,我将无法将提交推送到 Tiger

  3. 还有另一个名为 Cat 的存储库,我刚刚发现我无法向其推送新提交。这让我很困惑,因为我在同一台笔记本电脑上;

  4. 所以我检查了我的 bitbucket 的“个人 Settings/SSH 密钥”,然后 BOOM!那里没有存储我笔记本电脑的 ssh 密钥!

那么我如何能够首先推送到 Tiger???我可能弄错了...但我确实记得我的笔记本电脑的 ssh 密钥存储在 bitbucket 中。

  1. 然后我继续尝试将笔记本电脑的 ssh 密钥保存到 bitbucket,但它说: Someone has already added that SSH key.

这到底是怎么回事?

有什么想法吗?

TL;DR

有关键见解(请原谅这里的措辞):

you're trying to add the same key to two different bitbucket accounts

这只是ssh认证的问题,可是ssh认证的大问题。每个 Bitbucket 帐户必须使用 唯一 public 密钥。

朗:怎么回事

Git 本身不包含身份验证。要执行分布式操作,您的 Git 软件 必须 连接到其他一些 Git 软件。两个软件版本不必相同——事实上,一些服务器可能根本不使用 (C) Git——只要它们都使用 Git 协议,但该协议没有身份验证。它只是假设在使用协议时,服务器和客户端已经完全相互信任。因此, 托管系统相信您是您声称的那个人之前,您必须以某种方式证明 您是。这是认证过程。

一般来说,身份验证包括建立某种用户身份。每个网络托管站点都有点不同(由于 $reasons,有时与实际美元有关,有时 $reasons 只是一个元变量)但是有两种通用和常见的方法来验证任何大 Git 托管站点:

  • http(s)(现在主要是 https-only,因为纯 http 非常不安全),或者
  • ssh.

https 身份验证具有最大的可变性,因为有许多 https 实现,每个实现都有 自己的 身份和授权技术,所以这是我们最少可以说的。但是,Bitbucket 和 GitHub 现在都使用基于 token 的身份验证,而不是基于 password 的身份验证。令牌和密码之间的区别本质上是,令牌是一个 结构化 密码,其中 (hidden-from-the-user) 结构包含额外信息。一个是让网站生成令牌(通常使用密码,也许还有一些用于 two-factor 身份验证的第二因素)。然后指示 Git 提供用户名和 token-as-the-password。这对验证您 托管站点。这里的用户名是你的身份,password-or-token是你的身份证明(小心保管!)。

要将此方法与 Git 一起使用,请使用以 https:// 开头的 URL。它们采用 https://<em>user</em>@<em>host/path/passed/to/host</em> 的形式(尽管您 可以把password/token放在这里,或者省略user部分,通常最简单的是包含用户,省略密码,这样只需要管理密码通过一些凭证系统)。

ssh 身份验证更加统一,这可能是因为 ssh 实现较少并且大多数都将其历史追溯到一个共同的起点。要通过 Git 使用 ssh 身份验证,请使用以 ssh:// 开头或具有 <em>user</em>@[= 形式的 URL 87=]主机</em>:<em>路径</em>,例如git@bitbucket.org:my/repo.git。 ssh系统使用public-key cryptography;这里没有涉及到密码,至少目前是这样。

您的 Git 软件本身不会进行任何身份验证,但它可以 使用 凭据助手 .它仅针对 https 身份验证这样做。这是高度可配置的,并且具有很多系统依赖性。这也不是原始问题的内容,所以我们将在这里讨论。

对 Git 和大型托管站点使用 ssh 身份验证

当您使用 ssh 进行身份验证时,会涉及到一个用户名,它就在 URL 中:ssh://<em>user</em> @<em>主机</em>/<em>路径</em><em>用户</em>@<em>主机</em>:<em>路径</em>ssh:// 部分(如果使用这种形式)和 at-sign `@ 和冒号(如果使用这种形式)是将出现在 URL.

中的文字字符

所有大型 Git 服务器 要求 您提供 user 部分作为文字字符串 git。也就是说,他们不会将您认证为 您自己 ,而是 git pseudo-user。这有很多技术原因,但它们都归结为“那样更容易,现在是惯例”。既然你要声称自己是这个gitpseudo-user,不是无论你真的是谁,主持人是需要通过其他方式弄清楚你真正是谁。大型 Git 服务器的做法是作弊。

如果我们查看 public-key 密码学,我们会发现它的工作原理是让您(或您的 Git 软件,或者在这种特殊情况下,ssh 程序——Git 字面意思运行s ssh 因为 Git 不包含 ssh 代码本身)提供 t 服务器一个 public 密钥:一长串 random-looking 字母和数字以及可能代表某种加密密钥的其他字符。 public 密钥之所以这样称呼是因为它不是 秘密!你可以向任何人展示它,尽管没有充分的理由 bruit it about.

除了这个 public 密钥,还有一对 private 密钥,你应该保密(小心保管,就像密码一样)。只要给定 public 密钥,任何人都可以轻松加密任何数据; private 密钥的持有者可以使用私钥轻松地解密 相同的数据,但是没有私钥的人不能。1 因此,当使用 ssh 时,您连接到服务器(在本例中为 Bitbucket)并声称自己是用户 git 并向他们发送一个 public 密钥。他们使用 public 密钥加密 randomly-chosen 字符串,您使用 private 密钥 decrypt 并发送返回,他们会看到您实际上拥有私钥。

但是:他们怎么知道 你是谁? 你自称是 git pseudo-user。这就是作弊的来源:每个 public/private key-pair 都有一个 unique public key.2因此,在某些时候——在您使用 ssh 连接 托管服务器之前很久——您必须使用 https(以及用户名和密码,以及可能是 2FA) 并上传到托管服务器 public 密钥 你打算稍后使用你的 ssh 连接。

此时,托管服务器(在本例中为 Bitbucket)在一个大的 table 或数据库中查找 所有 public 键 .如果你刚刚给他们的 public 密钥 已经在 table 中,他们会给你你看到的错误:

Someone has already added that SSH key.

那个某人可能就是你。事实上,假设 public 键的唯一性,它 必须 是你!他们没有告诉你是谁,他们只是告诉你你现在不能添加这个,因为我,bitbucket,已经有了它。 (如果你想知道他们认为这个特定的 public 密钥代表谁,你只需 运行 ssh -T git@bitbucket.com:你也有私钥,你的 ssh 将使用它来解密他们发送什么,你就会成功登录,他们会告诉你他们认为你是谁。)

假设密钥 不是 在他们的大 table / 数据库中,他们添加它, 连同您曾经使用过的用户名使用 https 登录他们的站点。现在托管服务器知道,如果将来有人——任何人!——出现并提供 那个 public 密钥,那个“某人”自称是 。如果那个人也可以解密他们作为挑战提供的随机字符串,那么那个人也有私钥,因此 你。


1不是,也就是说,没有像足够强大的量子计算机这样非常神奇的东西。 "Post-quantum" cryptography,正如链接文章中所讨论的那样,是为了抵御这种未来的威胁。

2这在任何技术意义上都不能保证,但是包含足够的额外数据和其他垃圾 public 关键,在任何 实用 意义上,它将始终是唯一的。 Git 本身与对象哈希 ID 存在相同的问题:它们只是 在实践中 唯一,在理论上不是。 In theory, theory and practice are the same, but in practice they're not. —Benjamin Brewster, most likely


你的情况发生了什么

不可能确定。也许您正在对一个存储库使用 https 身份验证,而对另一个存储库使用 ssh 身份验证。

但是,您现在知道您可以 运行 ssh -T git@bitbucket.org 了解 他们认为您是谁 。这是基于您提供给他们的 public 密钥。如果您需要在 Bitbucket 上拥有多个帐户,则需要仔细控制您提供的 public 密钥。

请注意,ssh 可以使用 代理程序 来存储 key-pairs:这使您可以避免将 key-pairs 直接存储在您的计算机上重新使用(例如,如果您正在通过共享的中间工作机器,您可能希望将 laptop-side 密钥保留在 non-shared 笔记本电脑上并使用代理将它们传递到共享机器仅在需要时短暂使用)。但是,当您 使用代理时,您将失去对在 ssh 协商中的哪个点提供哪些密钥的控制。 .ssh/config 文件允许您指定仅应给出一些 特定的 密钥。您还可以使用此机制来说明您的 ssh 应该提供 pseudo-user git 用户名:参见,例如 (这个问题可以追溯到 Bitbucket 还是一个Mercurial 服务器,在过渡期间)。