中间人攻击和SSL

时间:2014-02-23 14:29:48

标签: security ssl openssl ssl-certificate man-in-the-middle

我正在使用OpenSSL通过HTTPS连接到我的一台服务器。但是,我似乎无法让服务器验证在客户端工作。根据我的理解,不验证证书让我对Man In the Middle攻击开放,但证书验证基本上是在寻找证书中的IP地址和域名来匹配。 (我说很多事情只是为了得到一些完整的详细回复:))

所以,如果它是我的服务器,我知道它的域名和IP地址,我使用SSL,我应该担心吗?然后,中间的人难道不能解密我的ssl数据,插入恶意代码,重新加密,然后转发我的服务器证书吗?

最后,如果MITM攻击是一个问题,如果我首先检查证书与另一个库验证,然后使用OpenSSL而不是验证?

是否还有其他可能发生的攻击?

2 个答案:

答案 0 :(得分:3)

  

但证书验证基本上是在证书中寻找匹配的IP地址和域名

证书将公钥绑定到实体(类似于个人或组织的身份)。绑定通过权威机构的签名进行。验证确保签名存在,并且提供证书的实体是他们所说的人。

识别对等方的方式是通过DNS名称。如果DNS被泄露,或者省略了主机名检查,则系统崩溃。

因此,您需要信任两者证书颁发机构 DNS。 DNS不提供真实性保证(或更准确地说,客户端不使用安全机制),因此您应将DNS视为不可信输入。


  

但是我似乎无法在客户端进行服务器验证。

使用OpenSSL,您需要在客户端中执行三项操作。首先,您需要确保服务器提供证书。其次,您需要验证链。第三,您需要执行主机名匹配,因为OpenSSL不会将其作为链验证的一部分。

服务器证书

您需要验证服务器是否有证书,因为某些协议和密码套件不需要证书。你可以用:

来做到这一点
X509* cert = SSL_get_peer_certificate(ssl);
if(cert) { X509_free(cert); }
if(NULL == cert) handleFailure();

链验证

如果您有自定义验证回调,这适用,但它适用于OpenSSL内置的标准验证和自定义验证回调。要从链验证中获取验证结果,请执行:

long res = SSL_get_verify_result(ssl);
if(!(X509_V_OK == res)) handleFailure();

主机名验证

1.0.2之前的OpenSSL 验证主机名。您必须从服务器的证书中提取主机名并确保其访问的站点。如果您想借用代码,请查看libcurl以及源文件ssluse.c中的验证程序。

如果您想针对规范执行手动验证,请参阅RFC 6125,Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)

为了完整起见,这里是如何获取证书的Subject Alternate Names(SAN)中存在的DNS名称。您可以从X509*等函数中获取SSL_get_peer_certificate

void print_san_name(X509* const cert)
{
    GENERAL_NAMES* names = NULL;
    unsigned char* utf8 = NULL;

    do
    {
        if(!cert) break; /* failed */

        names = X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0 );
        if(!names) break;

        int i = 0, count = sk_GENERAL_NAME_num(names);
        if(!count) break; /* failed */

        for( i = 0; i < count; ++i )
        {
            GENERAL_NAME* entry = sk_GENERAL_NAME_value(names, i);
            if(!entry) continue;

            if(GEN_DNS == entry->type)
            {
                int len1 = 0, len2 = -1;

                len1 = ASN1_STRING_to_UTF8(&utf8, entry->d.dNSName);
                if(!utf8) continue;
                len2 = (int)strlen((const char*)utf8);

                /* If there's a problem with string lengths, then     */
                /* we skip the candidate and move on to the next.     */
                /* Another policy would be to fail since it probably  */
                /* indicates the client is under attack.              */
                if(len1 != len2) {
                    fprintf(stderr, "Strlen and ASN1_STRING size do not match
                            "(embedded null?): %d vs %d\n", len2, len1);

                    /* Potential problem with the DNS name. Skip it */
                    /* TODO: test against IDNs                      */
                    OPENSSL_free(utf8), utf8 = NULL;

                    continue;
                }

                /* Perform matching here */
                fprintf(stdout, "  SAN: %s\n", utf8);

                OPENSSL_free(utf8), utf8 = NULL;
            }
            else
            {
                fprintf(stderr, "  Unknown GENERAL_NAME type: %d\n", entry->type);
            }
        }

    } while (0);

    if(names)
        GENERAL_NAMES_free(names);

    if(utf8)
        OPENSSL_free(utf8);    
}

TLS Client的OpenSSL wiki上有一个示例程序。它涵盖了服务器证书和链验证。您必须提供主机名验证的代码。


  

根据我的理解,不验证证书让我对中间人攻击开放

如果您不执行验证,您也可以保存周期并选择ADH之类的匿名方案。


  

所以,如果它是我的服务器,我知道它的域名和IP地址,我使用SSL,我应该担心吗? ...如果MITM攻击是一个问题,如果我首先检查证书与另一个库进行验证,然后使用OpenSSL而不是验证? ......还有其他可能发生的攻击吗?

它有很多,而且没有一个答案。由于您正在构建了解服务器先验的客户端,因此请考虑转向固定方案,以便您可以放弃信任CA和DNS。例如,参见OWASP的Certificate and Public Key Pinning

另外,阅读Peter Guttman的Engineering Security。本书的重要部分讨论了PKI,SSL,TLS和人类行为的系统性缺陷;以及如何改善您的安全状况。

答案 1 :(得分:1)

基本上Https有两个验证:

i)验证服务器/客户端针对彼此信任存储提供的证书。    为此,您必须为服务器/客户端实例实现密钥库/信任库,并将您的证书添加到密钥库,并将可信证书添加到信任库。这将完成证书验证。

仅供参考:Keystore and truststore

ii)另一方面,HTTPS将进行主机名验证,以防止中间人攻击。基本上,如果https url中指定的ip与证书提供的CommonName匹配,则此验证方法将返回“true”。如果您知道要信任哪个IP,则可以覆盖此验证方法。 仅供参考:Hostname verification