35

IP のリストをスキャンし、その IP の証明書から共通名を取得する必要があります (ポート 443 接続を許可するすべての IP について)。sockets と ssl モジュールを使用してこれを成功させることができました。有効な署名付き証明書を持つすべての IP で機能しますが、自己署名証明書では機能しません。

この方法を使用する場合、CA バンドルによって検証された有効な証明書が必要です。

from socket import socket
import ssl

s = socket()
c = ssl.wrap_socket(s,cert_reqs=ssl.CERT_REQUIRED, ca_certs='ca-bundle.crt')
c.connect(('127.0.0.1', 443))

print c.getpeercert()

を削除するcert_reqs=ssl.CERT_REQUIREDと、接続されますが、証明書がまったく取得されません。

ca-bundle に対して検証するかどうかに関係なく、IP 上の証明書の共通名を取得するにはどうすればよいですか?

4

3 に答える 3

49

python ssl ライブラリは、有効な署名がある場合にのみ証明書を解析するようです。

    """Returns a formatted version of the data in the
    certificate provided by the other end of the SSL channel.
    Return None if no certificate was provided, {} if a
    certificate was provided, but not validated."""

この関数を使用してサーバー証明書を取得することはできますが、証明書ssl.get_server_certificate()は PEM 形式で返されます。c.getpeercert(True)(または、検証済みかどうかに関係なく、バイナリ DER 形式で証明書を返す を呼び出すこともできます。)

>>> print ssl.get_server_certificate(('server.test.com', 443))
-----BEGIN CERTIFICATE-----
MIID4zCCAsugAwIBA.....

ここから、M2Crypto または OpenSSL を使用して証明書を読み取り、値を取得します。

# M2Crypto
cert = ssl.get_server_certificate(('www.google.com', 443))
x509 = M2Crypto.X509.load_cert_string(cert)
x509.get_subject().as_text()
# 'C=US, ST=California, L=Mountain View, O=Google Inc, CN=www.google.com'

# OpenSSL
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
x509.get_subject().get_components()
#[('C', 'US'),
# ('ST', 'California'),
# ('L', 'Mountain View'),
# ('O', 'Google Inc'),
# ('CN', 'www.google.com')]
于 2011-10-07T18:19:39.070 に答える
7

Mac では、swig と M2Crypto をインストールする必要があります。

端末の実行時:

brew install swig

その後:

sudo pip install m2crypto

次に、上記のコードを実行できます。

from socket import socket
import ssl
import M2Crypto
import OpenSSL

# M2Crypto
cert = ssl.get_server_certificate(('www.google.com', 443))
x509 = M2Crypto.X509.load_cert_string(cert)
print x509.get_subject().as_text()
# 'C=US, ST=California, L=Mountain View, O=Google Inc, CN=www.google.com'

# OpenSSL
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
print x509.get_subject().get_components()
#[('C', 'US'),
# ('ST', 'California'),
# ('L', 'Mountain View'),
# ('O', 'Google Inc'),
# ('CN', 'www.google.com')]
于 2015-06-21T12:46:02.377 に答える