【问题标题】:SSL/TLS without certificates没有证书的 SSL/TLS
【发布时间】:2011-12-23 18:41:03
【问题描述】:

我正在从事一个宠物项目,该项目将(最终完成后)允许安全的文件传输(不仅限于此,但其余部分并不特别相关)。我想使用 OpenSSL 库,因为它似乎是最完整的免费密码库(除了 SSL/TLS 之外,我还需要支持基本的对称加密和散列)。

我正在寻求实现一种与 SSH 类似的安全方案。基本上,用户会使用 TLSv1 (SSLv3.1) 连接到我的计算机。无论安全性如何,我都希望连接成功。然后,我希望能够检查用户使用的公共 key(不是整个证书)。该密钥将与已知的公钥进行比较,如果匹配,则允许用户访问特定的命令集。如果不匹配,用户可以选择使用连接申请将他/她的公钥添加到我的收藏中,但除此之外将无法访问我的服务。

我在这里没有任何特别需要证书。如果我可以跳过所有证书详细信息并仅使用原始加密密钥,那对我来说会简单得多。这是因为此模型遵循网络信任模型,而不是大多数 SSL/TLS 连接使用的分层模型,因此我不需要任何 CA 或签名证书。

不幸的是,大部分 OpenSSL 的文档都不存在。我发现的所有相关文章似乎都在设置“标准”SSL/TLS 连接,其中服务器的证书一直经过验证,直到一组根证书。这可能很有用,但我很难弄清楚如何启动和运行这些非传统 SSL 连接。

任何人都可以提出任何文章或文档来帮助我弄清楚如何实现这一点吗?

(OpenSSL 的使用并不是一成不变的,如果它提供了更好的方法来实现这一点,以及散列 [SHA-512] 和对称加密 [AES],我可以切换到另一个库。我是目标是 Linux,但如果最终产品可以移植到 Windows 上就更好了,这样我的朋友们也可以使用它。)

【问题讨论】:

  • 将公钥与公钥列表进行比较本质上是使用密码,这破坏了 https 和 ssl 的整个 PKI 特性。如果您同时控制客户端和服务器软件(因此您可以配置信任关系),那么创建和使用自签名证书的建议是一个很好的建议。
  • @AdamLiss,不,它与密码不同:用户不必发送私钥,而用户必须发送密码。 (并且比较列表中的自签名证书与比较它们的公钥几乎相同。)
  • 我没有使用 PKI。这个想法是,如果你是我的“朋友”(我有你的公钥/证书),那么你可以从我的计算机下载文件(我指定的)以及我可以从我的朋友那里下载的文件。问题是你看不到文件来自哪里(也就是说,如果 A 和 B 是朋友,B 和 C 是朋友,A 可以通过 B 从 C 下载,但根本不知道 C) .至少,简而言之就是这个想法。 OneSwarm 给了我这个项目的灵感。
  • 对了,你已经决定好语言了吗?您是否也查看过 LibNSS,它似乎有据可查 mozilla.org/projects/security/pki/nss/ref/ssl
  • 我还没有完全决定一种语言(我还在研究我想使用哪些库,以及程序/协议的规范),但我很可能会使用 C . 我可能改用 D。这真的取决于库比什么都重要——确切的语言对我来说并不重要。

标签: openssl ssl


【解决方案1】:

扩展尤金的回答(我会将此作为评论,但它有点长)...

在使用FOAF+SSL project(后来更名为 WebID)完成此类事情后,坚持使用 X.509 证书使实施更容易,因为大多数 SSL/TLS 堆栈在设计时都考虑到了它们(并且它们的 API 反映了这一点)。

上次我检查 FOAF+SSL 时,传统的 PKI 检查仍然存在,以便客户端检查服务器证书。另一个类似于 SSH 的选项是在您第一次遇到公钥/证书时接受它,并在它更改时警告用户。无论如何,这或多或少是 SSH 的工作方式(特别是,我猜很少有人在他们第一次看到密钥的指纹时会真正在带外检查它)。

仅考虑客户端证书的使用(尽管其中一些可能以类似的方式适用于服务器证书):

  • 大多数服务器库似乎都能够处理 X.509 证书,但您可以更改它们的验证方式(例如,Java 中的 X509TrustManager)。
  • 虽然您无法信任客户端证书所说的任何内容,除非您以其他方式验证它,但能够嵌入一些额外信息(例如主题 DN 或主题备用名称以查看用户声称的身份) 可以帮助 (a) 用户组织他们的证书和 (b) 提示验证者知道要寻找什么。裸露的公钥可能难以管理。
  • 许多现有的客户端工具(尤其是浏览器)在进行 SSL/TLS 客户端身份验证时使用 X.509 证书。配置客户端以使用自签名 X.509 证书(与来自 PKI 的证书相反)不需要做太多工作。 (支持 OpenPGP for TLS 的工具很少,我不确定是否有任何工具能够将其用作客户端证书的一种形式。)
  • 由于没有外部检查您将无法信任证书,因此它是否自签名(即颁发者和主题是否相同)并不重要,至少假设用户不会不要向您发送它不同意的证书(因此不必用自己的密钥密封)。这样做的结果是您可以构建一个服务来很容易地颁发证书。例如,浏览器内密钥生成对于不想使用opensslkeytool 命令的用户来说很方便。 Here 是一个示例服务,它将使用用户想要的 SAN 颁发证书(如果您检查 FOAF+SSL/WebID 项目,可能会有更新的版本)。无论此类服务使用哪个私钥或颁发者名称都无关紧要,但由于浏览器是围绕传统 PKI 设计的,因此使用真正的自签名证书并不容易。

在要求特定客户证书时也存在问题。 TLS 1.1 规范明确允许空 certification authorities(参见 RFC 4346),而 TLS 1.0 对此主题保持沉默。实际上,即使使用 TLS 1.0,大多数客户端工具似乎都对空列表感到满意(它们只会提供更多选择)。如果您希望系统的证书易于识别,您可以为所有这些证书使用相同的颁发者 DN,即使它们在实践中没有使用相同的私钥签名(同样,因为您会忽略签名)。

【讨论】:

  • 这个想法是我会生成一个邀请码并将该码提供给朋友。除了代码,我还会输入一些关于我的新朋友的详细信息(特别是他们所在的地址,例如 ethan.no-ip.org)。当他们发送“应用程序”时,他们使用邀请码,也可以发送消息。该程序将检查以确保邀请是正确的,并且我输入的地址在应用程序创建时解析为应用程序的来源。我也可以这样做,以便您手动检查消息。这个想法是,这就是您验证新“朋友”的方式。
【解决方案2】:

使用自签名证书 - 这与“原始”密钥相同,但更易于管理(请参阅 this question,了解如何在 openssl 中接受或不接受自签名证书)。

【讨论】:

  • 所以答案是“根本没有不使用证书的简单方法。使用自签名证书更容易。”?我想这行得通。我仍然可以跳过加载任何根证书,对吧?我想显而易见的后续行动是:我可以强制 OpenSSL 接受自签名证书吗?
  • @Ethan,仅限制对自签名证书的访问(并拒绝其他证书)是没有意义的。如果您愿意接受任何自签名证书,那么您不妨接受任何东西,因为您将无法检查颁发者 DN 是否是他们所说的(仅使用证书),无论是否颁发者 DN = 主题 DN 变得无关紧要。
  • @Ethan 通常 SSL 支持使用 OpenPGP 密钥或预共享密钥进行身份验证。但这些都不适合。至于只接受自签名 - 您可以动态控制要信任的内容,我猜在其他检查中,OpenSSL 应该让您检查证书是否是自签名的(其颁发者和主题字段必须相同)。
  • @Bruno,我想如果我忽略证书的其余部分而只使用公钥,这是有道理的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 2020-09-28
  • 2019-03-13
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
相关资源
最近更新 更多