Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么赢了';这段Python代码不能通过SSL连接吗?_Python_Sockets_Ssl - Fatal编程技术网

为什么赢了';这段Python代码不能通过SSL连接吗?

为什么赢了';这段Python代码不能通过SSL连接吗?,python,sockets,ssl,Python,Sockets,Ssl,已更新:问题底部的固定/工作代码。重新实现为使用wrap_socket()而不是SSL.Context()。协商密码似乎不受ssl协议的影响 我有一个XML服务,它监听端口8388。该服务内置了自己的CA,并将为在其管理界面上配置的任何客户端发出P12文件(我需要在连接中包含CA证书) 我已经配置了客户端并下载了P12文件;还从P12导出了PEM文件(为了便于调试),并为服务器CA导出了PEM文件(这是一个Java密钥库) 如果我使用openssl s_client并将客户端证书/密钥和CA文件

已更新:问题底部的固定/工作代码。重新实现为使用
wrap_socket()
而不是
SSL.Context()
。协商密码似乎不受ssl协议的影响

我有一个XML服务,它监听端口8388。该服务内置了自己的CA,并将为在其管理界面上配置的任何客户端发出P12文件(我需要在连接中包含CA证书)

我已经配置了客户端并下载了P12文件;还从P12导出了PEM文件(为了便于调试),并为服务器CA导出了PEM文件(这是一个Java密钥库)

如果我使用
openssl s_client
并将客户端证书/密钥和CA文件提供给它,事情似乎正常工作;ie:验证以下截断输出中的返回值:1。openssl进程不会在服务器上生成任何证书错误(就像我的Python脚本一样)。从我所读到的,这意味着证书都是正确有效的

# openssl s_client -connect srv.domain.net:8388 -CAfile server_ca.pem  -cert client_cert.pem -key client_key.pem
CONNECTED(00000003)
depth=1 ... emailAddress = ca@SERVERsystems.com
verify return:1
depth=0 ...CN = srv.domain.net
verify return:1
---
Certificate chain
 0 s:/emailAddress=help@mydomain.net...CN=srv.domain.net
   i:/C=US/...emailAddress=ca@SERVERsystems.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIJRDCCByygAwIBAgIGAVGIopaoMA0GCSqGSIb3DQEBDQUAMIG...rV
-----END CERTIFICATE-----
subject=/emailAddress=help@mydomain.net...CN=srv.domain.net
issuer=/C=US/...emailAddress=ca@SERVERsystems.com
---
Acceptable client certificate CA names
/C=US/...emailAddress=ca@SERVERsystems.com
/.../CN=srv.domain.net
---
SSL handshake has read 3369 bytes and written 5705 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: ...DF6572FA00D62D83CF0B1A82F
    Session-ID-ctx: 
    Master-Key: ...7F685C0B163A7739C271E9722FC0554108175C4
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1461337153
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
我现在正试图使用相同的证书、密钥和CA文件将Python(2.7.9)脚本连接到XML服务,但我无法让它工作。Python正在抱怨SSLv3错误,服务器表示无法验证客户端。因此,连接是有效的,但握手、证书或密码等都不正确

我已经搜索了许多示例和实现,而这一个似乎是最简单的一个,所以我开始用它作为模板。SSL3不是我会坚持的协议(POODLE),但它应该来自一个工作示例,所以我想做尽可能少的更改以使事情正常工作,然后从那里调整。有人知道我这里做错了什么吗?输出/错误/日志张贴在最底部

#!/usr/bin/python
# -*- coding: utf-8 -*- 

import socket
import OpenSSL
from OpenSSL import *
import sys

serverName = sys.argv[1]
print "Using server : " + serverName

ctx = SSL.Context(SSL.SSLv3_METHOD)

ctx.use_privatekey_file('client_key.pem')
ctx.use_certificate_file('client_cert.pem')
ctx.load_verify_locations(cafile='server_ca.pem')

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((serverName, 8388))
sslSocket = socket.ssl(s)

print repr(sslSocket.server())
print repr(sslSocket.issuer())

print ("writing socket..")
sslSocket.write('<transaction><data>14</data></transaction>\n')
s.close()
工作代码:

#!/usr/bin/python
# -*- coding: utf-8 -*- 
import socket
import ssl
import sys
import os

serverName = sys.argv[1]
print "Using server : " + serverName

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# ssl.PROTOCOL_xxx does not seem to affect negotiated cipher??
wrapper = ssl.wrap_socket(s,
                           ca_certs = "server_ca.pem",
                           certfile = "client_cert.pem",
                           keyfile  = "client_key.pem",
                           cert_reqs=ssl.CERT_REQUIRED,
                           ssl_version=ssl.PROTOCOL_TLSv1)

wrapper.connect((serverName, 8388))

# some info on the connnection/cipher in use
print repr(wrapper.getpeername())
print repr(wrapper.cipher())
print repr(wrapper.getpeercert())

# send server command
print ("writing socket..")
wrapper.send ("<transaction><data>14</data></transaction>\n")

# read server reply
print "server reply: " +  wrapper.recv(4096)
wrapper.close()
s.close()
#/usr/bin/python
#-*-编码:utf-8-*-
导入套接字
导入ssl
导入系统
导入操作系统
serverName=sys.argv[1]
打印“使用服务器:”+serverName
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#ssl.PROTOCOL_xxx似乎不会影响协商密码??
wrapper=ssl.wrapp_套接字,
ca\u certs=“server\u ca.pem”,
certfile=“client\u cert.pem”,
keyfile=“client\u key.pem”,
证书要求=ssl.cert要求,
ssl_version=ssl.PROTOCOL_TLSv1)
wrapper.connect((服务器名,8388))
#有关正在使用的连接/密码的一些信息
打印报告(wrapper.getpeername())
打印报告(wrapper.cipher())
打印报告(wrapper.getpeercert())
#发送服务器命令
打印(“书写插座…”
wrapper.send(“14\n”)
#读取服务器应答
打印“服务器回复:”+wrapper.recv(4096)
wrapper.close()
s、 关闭()
使用客户端证书创建SSL上下文时,在SSL连接中不使用此上下文。这意味着不会发送客户端证书,服务器会相应地进行投诉


使用客户端证书的一种更简单的方法是使用
ssl.wrap_socket
certfile
keyfile
参数,请参见。

也许这不是问题的原因,但您将不工作的python代码限制为ssl 3.0,而openssl成功地使用了TLS 1.2。请删除此限制后重试。您是指
ctx=SSL.Context(SSL.SSLv3_方法)
?无论我设置了什么协议(SSL.SSLv23_方法、TLSv1_方法、TLSv1_2_方法),我仍然会得到相同的
sslv3警报错误证书。我很困惑。。服务器是否规定了这一点?据我所知,服务器不希望接受您的客户端证书。因此,至少您现在知道,此错误不是特定于SSL/TLS版本的。从我看到的情况来看,您构建了上下文,但您没有将此上下文用于SSL连接。这样就不会使用客户端证书,这就是为什么会收到此错误消息。为什么不简单地使用ssl.wrap_socket
和证书、密钥和CA的参数呢?啊!好多了!非常感谢。如果你把你的建议转化为一个答案,我可以标记这个答案。谢谢!我已经用工作代码更新了这个问题,使用的是
ssl.wrap\u socket
Apr 22 10:39:56 srv.domain.net ERROR server.auth [Thread-183,run:233] Couldn't validate the client certificate.  Verify the validity and dates of the client cert.
Apr 22 10:39:56 srv.domain.net javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
Apr 22 10:39:56 srv.domain.net at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:431)
Apr 22 10:39:56 srv.domain.net at com.xml.server.auth.run(auth.java:226)
Apr 22 10:39:56 srv.domain.net at java.lang.Thread.run(Thread.java:745)
#!/usr/bin/python
# -*- coding: utf-8 -*- 
import socket
import ssl
import sys
import os

serverName = sys.argv[1]
print "Using server : " + serverName

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# ssl.PROTOCOL_xxx does not seem to affect negotiated cipher??
wrapper = ssl.wrap_socket(s,
                           ca_certs = "server_ca.pem",
                           certfile = "client_cert.pem",
                           keyfile  = "client_key.pem",
                           cert_reqs=ssl.CERT_REQUIRED,
                           ssl_version=ssl.PROTOCOL_TLSv1)

wrapper.connect((serverName, 8388))

# some info on the connnection/cipher in use
print repr(wrapper.getpeername())
print repr(wrapper.cipher())
print repr(wrapper.getpeercert())

# send server command
print ("writing socket..")
wrapper.send ("<transaction><data>14</data></transaction>\n")

# read server reply
print "server reply: " +  wrapper.recv(4096)
wrapper.close()
s.close()
ctx.use_privatekey_file('client_key.pem')
ctx.use_certificate_file('client_cert.pem')
...
sslSocket = socket.ssl(s)