OpenSSL s_客户端和Python SSL模块对主机名的证书存在分歧
我有个奇怪的问题。看起来OpenSSL的“s_client”工具不喜欢我的AppEngine应用程序的SSL证书,甚至不承认它(“没有对等证书可用”),但Python的SSL模块报告颁发者、日期范围、序列号、主题等,就好像根本没有问题一样 我假设我的SSL证书存在一些微妙的错误配置,但是,由于AppEngine提供了一个非常简单的上传证书的向导,说有错误配置就是说Google的功能被破坏了。。。我对此表示怀疑 如果有其他人经历过的话,我想了解一下这一点 s_客户:OpenSSL s_客户端和Python SSL模块对主机名的证书存在分歧,python,google-app-engine,ssl,openssl,ssl-certificate,Python,Google App Engine,Ssl,Openssl,Ssl Certificate,我有个奇怪的问题。看起来OpenSSL的“s_client”工具不喜欢我的AppEngine应用程序的SSL证书,甚至不承认它(“没有对等证书可用”),但Python的SSL模块报告颁发者、日期范围、序列号、主题等,就好像根本没有问题一样 我假设我的SSL证书存在一些微妙的错误配置,但是,由于AppEngine提供了一个非常简单的上传证书的向导,说有错误配置就是说Google的功能被破坏了。。。我对此表示怀疑 如果有其他人经历过的话,我想了解一下这一点 s_客户: openssl s_clien
openssl s_client -connect www.abc.com:443
s_客户端输出:
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}
问题是我没有在“s_客户端”调用中包含“servername”参数。问题是我没有在“s_客户端”调用中包含“servername”参数。可能是SNI问题(您的Python客户端可能正在使用它,具体取决于支持什么),使用
-servername
选项尝试s\u客户端
。这也可能是SSL/TLS版本问题,请尝试使用-ssl3
,-tls1
,-no\u ssl3
,-no\u tls1
,…我的AppEngine是为SNI配置的,是的。这是一个很好的建议,但似乎没有告诉我什么。虽然-ssl1,-ssl2列在帮助中,但它表示它们是无效的选项。传递-tls1、-tls1_1和-tls1_2没有什么区别。我愿意接受AppEngine期望的SSL版本在理论上我无法提供,但我怀疑我只能支持Google不支持的版本。区别更可能在-ssl3
和tls1
之间openssl s_client-connect www.abc.com:443-servername www.abc.com-tls1
应该会有所不同。实际上。。我实际上缺少了“servername”参数。谢谢。可能是SNI问题(您的Python客户端可能正在使用它,具体取决于支持的内容),请使用-servername
选项尝试s_-client
。这也可能是SSL/TLS版本问题,请尝试使用-ssl3
,-tls1
,-no\u ssl3
,-no\u tls1
,…我的AppEngine是为SNI配置的,是的。这是一个很好的建议,但似乎没有告诉我什么。虽然-ssl1,-ssl2列在帮助中,但它表示它们是无效的选项。传递-tls1、-tls1_1和-tls1_2没有什么区别。我愿意接受AppEngine期望的SSL版本在理论上我无法提供,但我怀疑我只能支持Google不支持的版本。区别更可能在-ssl3
和tls1
之间openssl s_client-connect www.abc.com:443-servername www.abc.com-tls1
应该会有所不同。实际上。。我实际上缺少了“servername”参数。谢谢