2012-02-01 56 views

回答

3

我不確定使用urllib2。不幸的是,我可以找到關於此最近的信息是this link和相關代碼:

import socket 
import ssl 

HOST = "www.google.com" 
PORT = 443 

# replace HOST name with IP, this should fail connection attempt 
HOST = socket.getaddrinfo(HOST, PORT)[0][4][0] 
print(HOST) 

# create socket and connect to server 
# server address is specified later in connect() method 
sock = socket.socket() 
sock.connect((HOST, PORT)) 

# wrap socket to add SSL support 
sock = ssl.wrap_socket(sock, 
    # flag that certificate from the other side of connection is required 
    # and should be validated when wrapping 
    cert_reqs=ssl.CERT_REQUIRED, 
    # file with root certificates 
    ca_certs="cacerts.txt" 
) 

# security hole here - there should be an error about mismatched host name 
# manual check of hostname 
cert = sock.getpeercert() 
for field in cert['subject']: 
    if field[0][0] == 'commonName': 
    certhost = field[0][1] 
    if certhost != HOST: 
     raise ssl.SSLError("Host name '%s' doesn't match certificate host '%s'" 
         % (HOST, certhost)) 

雖然文件中的註釋是相當廣泛的,在第一個鏈接的維基還列出了這些指令:

要驗證證書是否與請求的站點匹配,您需要檢查證書的subject中的commonName字段。該信息可以通過getpeercert()包裝套接字的方法進行訪問。

您將需要cacerts.txt文件,其中包含放置在腳本旁邊的根證書 - 請參閱下面的如何獲取更新列表。要檢查證書驗證是否有效 - 請使用https://www.debian-administration.org/HOST名稱。此網站的證書未由來自cacerts.txt的任何根證書籤名,因此您將收到錯誤消息。

你可以看着pyopenssl module爲好,根據我張貼的第一環節,因爲它可以用來以這種方式來驗證SSL證書:

import socket 
from OpenSSL import SSL 

HOST = "www.google.com" 
PORT = 443 

# replace HOST name with IP, this should fail connection attempt, 
# but it doesn't by default 
HOST = socket.getaddrinfo(HOST, PORT)[0][4][0] 
print(HOST) 

# uses HOST 
def verify_cb(conn, x509, errno, errdepth, retcode): 
    """ 
    callback for certificate validation 
    should return true if verification passes and false otherwise 
    """ 
    if errno == 0: 
    if errdepth != 0: 
     # don't validate names of root certificates 
     return True 
    else: 
     if x509.get_subject().commonName != HOST: 
     return False 
    else: 
    return False 

context = SSL.Context(SSL.SSLv23_METHOD) 
context.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb) 
context.load_verify_locations("cacerts.txt") 

# create socket and connect to server 
sock = socket.socket() 
sock = SSL.Connection(context, sock) 
sock.connect((HOST, PORT)) 
sock.do_handshake() 

根據第一文檔鏈接,這些示例需要here的最新證書版本。

相關問題