我正在尝试使用python创建套接字连接。
这是我的python代码......
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.settimeout(config['timeout'])
self.socket.connect((config['host'], config['port']))
self.ssl = ssl.wrap_socket(
self.socket,
certfile=config['certificate'],
keyfile=config['key']
)
它不起作用,因为远程服务器的证书似乎是自签名或信任存储中丢失的。我是python的新手,无法弄清楚如何在python中禁用verify_peer,因此连接可以正常工作。
我在php中有工作代码......
$context = stream_context_create([
'ssl' => [
'verify_peer' => false,
'local_cert' => $config['certificate'],
'local_pk' => $config['key']
]
]);
$socket = stream_socket_client(
'ssl://secure.test.com:700',
$errno, $errstr, $config['timeout'],
STREAM_CLIENT_CONNECT, $context
);
设置'verify_peer' => false
有助于建立连接。我怎么能在python中做那样的事情?
openssl debug
openssl s_client -connect secure.test.com:700
verify error:num=20:unable to get local issuer certificate
verify return:1
verify error:num=21:unable to verify the first certificate
verify return:1
请帮忙并提出建议。感谢
答案 0 :(得分:0)
只需添加cert_reqs = ssl.CERT_NONE
即可停用证书验证。但是,只有禁用证书验证是一个非常糟糕的主意,因为您知道对man-in-the-middle attacks 开放。
因此,您应该检查证书是否是预期的证书。使用自签名证书(以及其他证书),您可以检查收到的证书是否与预期的证书指纹匹配,如下面的代码所示:
import socket
import ssl
import hashlib
dst = ('www.paypal.com',443)
fp_expected = '0722d46c216327bab8075f5db57ebed64d80e6699204c249c3f6ea9cc281c15b'
# connect to the target with TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(dst)
# upgrade the socket to SSL without checking the certificate
s = ssl.wrap_socket(s,cert_reqs = ssl.CERT_NONE)
# get certificate, compute fingerprint and check against expected value
cert_bin = s.getpeercert(True)
fp = hashlib.sha256()
fp.update(cert_bin)
assert(fp.hexdigest() == fp_expected)