背景之前利用笨重的Java寫過內(nèi)網(wǎng)訪問程序(SSL雙向認(rèn)證系統(tǒng)),今天才發(fā)現(xiàn)curl等命令對(duì)SSL都有良好的支持。
故記錄相關(guān)點(diǎn)滴。
創(chuàng)建CA根證書
#創(chuàng)建ca私鑰
openssl genrsa -out ca.key
#創(chuàng)建證書請(qǐng)求文件(Certificate Secure Request)
openssl req -new -key ca.key -out ca.csr
#創(chuàng)建CA根證書
openssl x509 -req -days 3650 -in ca.csr -signkey ca.key -out ca.crt
創(chuàng)建服務(wù)器證書
#創(chuàng)建服務(wù)器私鑰
openssl genrsa -out server.key
#創(chuàng)建服務(wù)器證書請(qǐng)求文件
openssl req -new -key server.key -out server.csr
#創(chuàng)建服務(wù)器證書
openssl ca -in server.csr -cert ca.crt -keyfile ca.key -out server.crt
PFX證書轉(zhuǎn)換
#pfx格式證書導(dǎo)出成pem格式證書
openssl pkcs12 -in jinli.pfx -nodes -out jinli.pem
#導(dǎo)出私鑰
openssl rsa -in jinli.pem -out jinli.key
#導(dǎo)出證書,公鑰
openssl x509 -in jinli.pem -out jinli.crt
curl訪問HTTPS命令
curl -E jinli.pem:${password} --cacert ca.crt https://www.cn.alibaba-inc.com/
curl --cacert gmail.pem https://mail.google.com/mail
curl --cert jinli.crt --key jinli.key --cacert ca.crt https://www.cn.alibaba-inc.com/
參數(shù)解釋:
--cacert <file> CA certificate to verify peer against (SSL)
--capath <directory> CA directory to verify peer against (SSL)
-E/--cert <cert[:passwd]> Client certificate file and password (SSL)
--cert-type <type> Certificate file type (DER/PEM/ENG) (SSL)
--key <key> Private key file name (SSL/SSH)
--key-type <type> Private key file type (DER/PEM/ENG) (SSL)
python訪問HTTPS代碼
from httplib import HTTPSConnection
con = HTTPSConnection('www.cn.alibaba-inc.com', cert_file='jinli.pem')
con.connect()
con.request('GET', '/xxx')
res = con.getresponse()
print res.status
print res.read()
res.close()
con.close()
python查看證書信息代碼
from OpenSSL import crypto
x509 = crypto.load_certificate(crypto.FILETYPE_PEM, open('cert_file').read())
print x509.get_issuer()
pkcs = crypto.load_pkcs12(open(pkcs_file).read(),passphrase)
print pkcs.get_certificate().get_issuer()
HTTPSConnection不理解的地方
def wrap_socket(sock, keyfile=None, certfile=None,
server_side=False, cert_reqs=CERT_NONE,
ssl_version=PROTOCOL_SSLv23, ca_certs=None,
do_handshake_on_connect=True,
suppress_ragged_eofs=True, ciphers=None):
return SSLSocket(sock, keyfile=keyfile, certfile=certfile,
server_side=server_side, cert_reqs=cert_reqs,
ssl_version=ssl_version, ca_certs=ca_certs,
do_handshake_on_connect=do_handshake_on_connect,
suppress_ragged_eofs=suppress_ragged_eofs,
ciphers=ciphers)
ssl wrap的函數(shù)是支持ca_certs參數(shù)的,但是HTTPSConnection不支持ca_certs參數(shù)
class HTTPSConnection(HTTPConnection):
"This class allows communication via SSL."
default_port = HTTPS_PORT
def __init__(self, host, port=None, key_file=None, cert_file=None,
strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
source_address=None):
HTTPConnection.__init__(self, host, port, strict, timeout,
source_address)
self.key_file = key_file
self.cert_file = cert_file
def connect(self):
"Connect to a host on a given (SSL) port."
sock = socket.create_connection((self.host, self.port),
self.timeout, self.source_address)
if self._tunnel_host:
self.sock = sock
self._tunnel()
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)