【问题标题】:How to connect to a server with a certificate and rsa key如何使用证书和 rsa 密钥连接到服务器
【发布时间】:2019-04-26 13:42:37
【问题描述】:

我对 python 编程很陌生。 我有一个证书和 RAS 密钥。我想编写一个 python ssl 套接字客户端程序来向服务器发送消息。我知道服务器主机名和端口。 我一直在尝试下面的代码。

请指导我。

我目前的代码是:

import socket
import ssl

context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile="D:/mycerti.crt", keyfile="D:/mykey.key") 

soc = socket.socket() 
soc.bind(('xxx.xxx.xxx.xxx', 3335)) # i am giving actual ip address not xx.xx.xx. 

soc.listen(5) 

但我不断收到以下错误:

Traceback (most recent call last): File "\test.py", line 7, in <module> soc.bind(('xxx.xxx.xxx.xxx', 3335)) OSError: [WinError 10049] The requested address is not valid in its context

我使用 openssl 套接字的方式存在错误,我更正了它。

context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)  # not CLIENT_AUTH
context.load_cert_chain(certfile="D:/mycerti.crt", keyfile="D:/mykey.key")

soc = socket.socket()
conn = context.wrap_socket(soc, server_hostname='your_server_hostname')  # name, not ip address

conn.connect(('xxx.xxx.xxx.xxx', 3335))

现在我没有收到上述错误,但现在我说错了。

Traceback (most recent call last): 
File "C:/Users/Nouman Yosuf/AppData/Local/Programs/Python/Python37-32/Test.py", line 10, in <module> conn.connect(('x.x.x.x', 3335)) 
File "C:\Users\Nouman Yosuf\AppData\Local\Programs\Python\Python37-32\lib\ssl.py", line 1150, in connect self._real_connect(addr, False) 
File "C:\Users\Nouman Yosuf\AppData\Local\Programs\Python\Python37-32\lib\ssl.py", line 1141, in _real_connect self.do_handshake() 
File "C:\Users\Nouman Yosuf\AppData\Local\Programs\Python\Python37-32\lib\ssl.py", line 1117, in do_handshake self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)

我还以 CA 和个人身份安装了证书。但我仍然遇到上述错误。我尝试指定证书路径,也在安装证书之后。但仍然无法验证证书说明无法获得本地颁发者证书。 我还尝试从头开始创建上下文。

context = ssl.SSLContext()
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True 
context.load_verify_locations("C:/mycerti.crt") 
soc = socket.socket() 
conn = context.wrap_socket(soc, server_hostname='x.x.x.x') 
conn.connect(('x.x.x.x.', 3335)) 

但我说错了。

 [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for 'x.x.x.x. (_ssl.c:1056) 

而且我确信证书是有效的或者那个 Ip.

【问题讨论】:

  • 下面是我正在尝试的代码。导入套接字 import ssl context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile="D:/mycerti.crt", keyfile="D:/mykey.key") soc = socket.socket() soc .bind(('xxx.xxx.xxx.xxx', 3335)) # 我给出的实际 IP 地址不是 xx.xx.xx。 soc.listen(5) 但我不断收到以下错误。 Traceback(最近一次调用最后一次):文件“\test.py”,第 7 行,在 soc.bind(('xxx.xxx.xxx.xxx', 3335)) OSError: [WinError 10049] The requested address在其上下文中无效
  • 上面写着"The requested address is not valid in its context"。显示您的地址。您是否在 Google 中查看过此消息和 WinError 10049?也许有人已经遇到过这个问题,他解决了。

标签: python openssl


【解决方案1】:

你很接近,但缺少几个概念。

首先,如果您是客户端,则将您的套接字“连接”到服务器。另一方面,服务器“绑定”到一个端口,“监听”传入的连接请求。 (同样,您需要使用 ssl.Purpose.SERVER_AUTH 而不是 ssl.Purpose.CLIENT_AUTH:如果您是服务器,则使用后者,希望对客户端进行身份验证)

其次,您确实为 SSL 创建了上下文,但您仍然需要将 SSLContext 与套接字本身相关联。为此,您使用wrap_socket。正如你所拥有的,你有一个上下文,你有一个套接字,但它们彼此不知道。打包后,您将使用该连接,而不是您原来的 soc。

请注意,wrap_socket 采用服务器名称,而不是 IP 地址。这是因为它将检查以确保您的服务器的证书与服务器提供的证书匹配(相同的 IP 可以托管许多命名服务器)。如果不匹配,则连接失败。

试试这样的:

import socket
import ssl

context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)  # not CLIENT_AUTH
context.load_cert_chain(certfile="D:/mycerti.crt", keyfile="D:/mykey.key")

soc = socket.socket()
conn = context.wrap_socket(soc, server_hostname='your_server_hostname')  # name, not ip address

conn.connect(('xxx.xxx.xxx.xxx', 3335))

# Connection made, so do something, like get the server's certificate
# and see when it expires...
ssl_info = conn.getpeercert()
print sl_info['notAfter']

【讨论】:

  • 非常感谢您的回复。是的,我在那里缺少一些基本概念。有时也想通了。我现在正在使用你的代码。但我一直低于错误。
  • 回溯(最近一次调用最后一次):文件“C:/Users/Nouman Yosuf/AppData/Local/Programs/Python/Python37-32/Test.py”,第 10 行,在 conn.connect(('x.x.x.x', 3335)) 文件“C:\Users\Nouman Yosuf\AppData\Local\Programs\Python\Python37-32\lib\ssl.py”,第 1150 行,连接 self._real_connect (地址,假)文件“C:\Users\Nouman Yosuf\AppData\Local\Programs\Python\Python37-32\lib\ssl.py”,第 1141 行,在 _real_connect self.do_handshake() 文件“C:\Users \Nouman Yosuf\AppData\Local\Programs\Python\Python37-32\lib\ssl.py",第 1117 行,在 do_handshake self._sslobj.do_handshake() 中
  • ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1056) 我已将证书安装为 CA 和个人证书。但我仍然遇到上述错误。
  • 我尝试指定证书路径以及安装证书之后。但仍然无法验证证书说明无法获得本地颁发者证书。
  • 我还尝试从头开始创建上下文。 context = ssl.SSLContext() context.verify_mode = ssl.CERT_REQUIRED context.check_hostname = True context.load_verify_locations("C:/mycerti.crt") #context.load_cert_chain(certfile="C:/mycerti.crt", keyfile= "C:/mykey.key") soc = socket.socket() conn = context.wrap_socket(soc, server_hostname='x.x.x.x') #名字,不是ip地址 conn.connect(('x.x.x.x.', 3335)) 但是我收到错误消息,提示 [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:IP 地址不匹配,证书对 'x.x.x.x. (_ssl.c:1056)
猜你喜欢
  • 2014-09-03
  • 2017-09-25
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多