繁体   English   中英

TLS:如何验证使用RSA密钥自签名的证书

[英]TLS: How to verify a certificate self-signed with an RSA key

我正在尝试使用OpenSSL和TLS来提供类似SSH的信任模型。 这意味着两个对等体每个都存储一个RSA密钥对,没有证书。 他们还在TLS会话建立之前交换了他们的公钥。 为了实现这一点,我使用了一些OpenSSL的未记录的函数,所以我仍然有疑问,这里是如何:

  • 在初始化期间,对等体生成内存中的临时x509证书。 它包含我可以逃脱的最小虚拟数据,即虚拟CN,发行者,以及到期前许多年。 无论如何都不会检查这些 设置SSL上下文以双向交换两个证书。

  • 重要的一步是证书包含主机的公钥,并使用私钥进行签名:

     EVP_PKEY *pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, PRIVKEY); X509_set_pubkey(x509, pkey); X509_sign(x509, pkey, EVP_sha384()); 
  • 此证书分配给SSL_CTX并用于整个应用程序生命周期。

我最担心的是TLS会话建立时的验证过程。 我正在使用SSL_CTX_set_cert_verify_callback(always_true_func)禁用OpenSSL执行的所有验证,并像我这样自己滚动:

X509 *received_cert = SSL_get_peer_certificate(conn_info->ssl);
EVP_PKEY *received_pubkey = X509_get_pubkey(received_cert);
if (EVP_PKEY_type(received_pubkey->type) != EVP_PKEY_RSA)
    error();
ret = X509_verify(received_cert, received_pubkey);
if (ret <= 0)
    error("trust_failed");

// Compare received public key with expected one
RSA *expected_rsa_key = read_RSA_key_from_disk();
EVP_PKEY expected_pubkey = { 0 };
EVP_PKEY_assign_RSA(&expected_pubkey, expected_rsa_key);
EVP_PKEY_cmp(received_pubkey, &expected_pubkey);

if (ret == 1)
    return true; // identity verified!
else
    return false;

问题:这是OpenSSL API的正确用法吗? 您是否看到任何安全漏洞,特别是在最后一部分,验证收到的密钥? 有没有更好的方法来实现相同的结果?

编辑:答案:要验证在TLS握手期间收到的自签名证书是否与存储的RSA密钥匹配, 则无需检查证书的签名 ,即不需要X509_verify 收到的公钥与预期公钥的比较就足够了。

原因是(引用OpenSSL项目核心开发人员Stephen Henson博士)“ 根据密码套件,服务器执行RSA解密操作或RSA签名操作。因此,如果握手成功完成,您可以确保相同的密钥用作证书中的一个 “。

证书将公钥和附加信息(例如标识符和其他属性)绑定在一起。 是什么使公钥和附加信息之间的关联成为证书签署的事实。

X.509证书由CA签名和颁发的原因是因为CA断言公钥与证书的其余内容(特别是其主题)之间的绑定。 这样做的目的是让知道CA的一方但不一定知道颁发证书的实体验证证书的内容是否为真,特别是公钥属于证书的主题。

由于您的身份验证方案依赖于预先知道谁拥有公钥或者拥有公钥的哪些知识,并且由于您将忽略证书的内容(除公钥之外),因此无需验证公钥之间的关联证书的其余部分为真(无论是否自签)。

您必须验证的是,您收到的公钥与您已知的公钥之一匹配。

编辑:

但其次是实际验证自签名证书是否有效签名,因为任何人都可以向我发送主机的公钥(它是公开的......)。

任何人都可以使用主机的公钥向您发送证书,但只有具有与该公钥匹配的私钥的实体才能协商主密钥。 如何完成这取决于密码套件,但只有具有私钥的服务器才能继续使用TLS连接。

客户端至少总是至少知道它已经与具有服务器证书中的公钥的私钥的实体建立了TLS连接(独立于知道该证书属于谁)。

这实际上完全独立于用于验证服务器身份的机制(传统上,PKI +主机名验证)。

如果您确定地知道主机的公钥(例如,通过在您已知的列表中查找),验证证书签名是无关紧要的(无论是自签名还是由您不知道的一方签名)。

这同样适用于客户端证书:如果发送证书的客户端无法使用与其发送的客户端证书匹配的私钥发送正确的签名(在证书验证消息中),则握手将无法完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM