OpenSSL s_client 和 Python SSL 模块对主机名的证书存在分歧

OpenSSL 的 “s_client” 工具不喜欢他的 AppEngine 应用程序的 SSL 证书,甚至不承认它 (“no peer certificate is available”),但 Python 的 SSL 模块报告了颁发者、日期范围、序列号、主题等,好像根本不存在问题。
在这里插入图片描述

提问者认为他的 SSL 证书存在一些微妙的错误配置,但由于 AppEngine 提供了一个非常简单的上传证书向导,因此说存在错误配置就等于说 Google 的功能失效了,这显然不太可能。

提问者希望有人曾经遇到过这种情况,并能提供一些见解。

s_client:

openssl s_client -connect www.abc.com:443

s_client 输出:

CONNECTED(00000003)
3073997000:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 225 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

Python 3.3 测试脚本:

import socket

from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23
from ssl import SSLContext  # Modern SSL?
from ssl import HAS_SNI  # Has SNI?

from pprint import pprint

# Stole this from "requests" package.
def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
                    ca_certs=None, server_hostname=None,
                    ssl_version=None):

    context = SSLContext(ssl_version)
    context.verify_mode = cert_reqs

    if ca_certs:
        try:
            context.load_verify_locations(ca_certs)
        # Py32 raises IOError
        # Py33 raises FileNotFoundError
        except Exception as e:  # Reraise as SSLError
            raise SSLError(e)

    if certfile:
        # FIXME: This block needs a test.
        context.load_cert_chain(certfile, keyfile)

    if HAS_SNI:  # Platform-specific: OpenSSL with enabled SNI
        return context.wrap_socket(sock, server_hostname=server_hostname)

    return context.wrap_socket(sock)

hostname = 'www.abc.com'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostname, 443))

sslSocket = ssl_wrap_socket(s,
                            ssl_version=2, 
                            cert_reqs=2, 
                            ca_certs='/usr/local/lib/python3.3/dist-packages/requests/cacert.pem', 
                            server_hostname=hostname)

pprint(sslSocket.getpeercert())
s.close()

测试脚本输出:

{'issuer': ((('countryName', 'US'),),
            (('organizationName', 'GeoTrust, Inc.'),),
            (('commonName', 'RapidSSL CA'),)),
 'notAfter': 'Oct  2 20:01:20 2014 GMT',
 'notBefore': 'Sep 29 02:17:38 2013 GMT',
 'serialNumber': '0E45AF',
 'subject': ((('serialNumber', 'd3tVuFeMunyn/gFFucMFHgZ2iBihdthR'),),
             (('organizationalUnitName', 'GT22884059'),),
             (('organizationalUnitName',
               'See www.rapidssl.com/resources/cps (c)13'),),
             (('organizationalUnitName',
               'Domain Control Validated - RapidSSL(R)'),),
             (('commonName', 'www.abc.com'),)),
 'subjectAltName': (('DNS', 'www.abc.com'),
                    ('DNS', 'abc.com')),
 'version': 3}

2、解决方案

根据第一个答案,问题在于没有在 “s_client” 调用中包含 “servername” 参数。可以通过在 “s_client” 调用中添加 “servername” 参数来解决此问题。

openssl s_client -connect www.abc.com:443 -servername www.abc.com

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值