2016-04-22 25 views
1

更新:問題の最後に固定された/作業コード。 SSL.Context()の代わりにwrap_socket()を使用するように再実装しました。交渉された暗号は、私は、サービスが(私は含める必要があり、それは内蔵の独自のCAのしていると、それの管理インターフェイスに設定されている任意のクライアントのためにP12ファイルを発行するポート8388.でリッスンするXMLサービスを持っているssl.PROTOCOL_なぜこのPythonコードはSSL経由で接続されませんか?

によって影響を受けそうです私の接続のCA証明書)。

クライアントを設定してP12ファイルをダウンロードしました。また、P12からPEMファイル(簡単なデバッグ用)をエクスポートし、サーバーCA(Javaキーストアである)のPEMファイルをエクスポートしました。

openssl s_clientを使用して、クライアント側の証明書/キーとCAファイルを使用すると、正しく動作するように見えます。すなわち、ベリファイリターン:1以下の切り捨てられた出力にあります。 opensslプロセスは(私のPythonスクリプトと同様に)サーバー上に証明書エラーを生成しません。私が読んだことから、これは証明書がすべてOKで有効であることを意味するはずです。

# 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 = [email protected] 
verify return:1 
depth=0 ...CN = srv.domain.net 
verify return:1 
--- 
Certificate chain 
0 s:/[email protected]=srv.domain.net 
    i:/C=US/[email protected] 
--- 
Server certificate 
-----BEGIN CERTIFICATE----- 
MIIJRDCCByygAwIBAgIGAVGIopaoMA0GCSqGSIb3DQEBDQUAMIG...rV 
-----END CERTIFICATE----- 
subject=/[email protected]=srv.domain.net 
issuer=/C=US/[email protected] 
--- 
Acceptable client certificate CA names 
/C=US/[email protected] 
/.../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) 
--- 

私は今のPython同じ証明書、キーおよびCAファイルを使用してXMLサービスへの(2.7.9)スクリプトをフックアップしようとしていますが、私はそれが働いて得ることができません。 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() 

Pythonの出力:上記の接続後

Using server : localhost 
Traceback (most recent call last): 
    File "./test3.py", line 29, in <module> 
    sslSocket = socket.ssl(s) 
    File "/usr/lib/python2.7/socket.py", line 64, in ssl 
    return _realssl.sslwrap_simple(sock, keyfile, certfile) 
    File "/usr/lib/python2.7/ssl.py", line 993, in sslwrap_simple 
    ssl_sock.do_handshake() 
ssl.SSLError: [SSL: SSLV3_ALERT_BAD_CERTIFICATE] sslv3 alert bad certificate (_ssl.c:581) 

Serverログ:

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() 
+0

これは問題の原因ではないかもしれませんが、非稼動のPythonコードをSSL 3.0に制限します。一方、opensslはTLS 1.2を使用しています。この制限を解除して再試行してください。 –

+0

'ctx = SSL.Context(SSL.SSLv3_METHOD)'を参照していますか?どんなプロトコルを設定しても(SSL.SSLv23_METHOD、TLSv1_METHOD、TLSv1_2_METHOD)、私は同じ 'sslv3 alert bad certificate'エラーを受けます。私は困惑しています..サーバーはそれを指示しますか? – Koko

+0

私の理解から、サーバーはあなたのクライアント証明書を受け入れたくありません。だから少なくとも、このエラーはSSL/TLSのバージョンに固有のものではないことがわかりました。 –

答えて

0
ctx.use_privatekey_file('client_key.pem') 
ctx.use_certificate_file('client_cert.pem') 
... 
sslSocket = socket.ssl(s) 

クライアント証明書を使用してSSLコンテキストを作成するときには、SSL接続内でこのコンテキストを使用しないでください。これは、クライアント証明書が送信されず、サーバーがそれに応じて不平を言うことを意味します。

クライアント証明書を使用するには、はるかに簡単な方法は、ssl.wrap_socketcertfilekeyfileパラメータを使用している、the documentationを参照してください。

+0

ありがとう!私は 'ssl.wrap_socket'を利用して作業コードで質問を更新しました。 – Koko

関連する問題